Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Different result running a query in SQL Server and from C#

I have an app that runs a stored procedure in SQL Server, checking the difference of times between one row in a table and getdate()

I call this stored procedure from c#, and use a @returnValue to do some things

This is the method

public static bool Check(string CheckStored)
{
    using (DbCommand command = DatabaseDA.DefaultDb.GetStoredProcCommand(CheckStored))
    {
        DatabaseDA.DefaultDb.AddParameter(command, "ReturnValue", DbType.Boolean, ParameterDirection.ReturnValue, "", DataRowVersion.Current, 0);
        DatabaseDA.DefaultDb.ExecuteNonQuery(command);

        return Convert.ToBoolean(command.Parameters["@ReturnValue"].Value);
    }
}

and this is the call

bool notifNeeded = NotificationsDA.Check("CheckLastEnvioListadoComprobanteEjercicio");

then in SQL Server I have:

ALTER Procedure [dbo].[CheckLastEnvioListadoComprobanteEjercicio]
as
Begin

declare @UltimoEnvio datetime
declare @ReturnValue bit 
select @UltimoEnvio = LastDate from EnvioListadoEjercicioComprobantes 

Select @returnValue = CASE 
                         WHEN DATEDIFF(hour, @UltimoEnvio, getdate()) >= 1 THEN 1
                         ELSE 0 
                      END   
from rep_inboxRequest

if (@ReturnValue = 1)
    update EnvioListadoEjercicioComprobantes set LastDate = getdate()

return @ReturnValue
END 

in EnvioListadoEjercicioComprobantes I have a row with the lastDate of one action (ej sending mail).

Right now, I have only one row, with 2012-06-18 06:40:02.210 value. I compare this date with the actual date, and return a bit if the difference is more than an hour.

Right now, in Argentina, its about 2012-06-18 11:26

If I execute getdate() in SQL Server, I get 2012-06-18 11:30:44.027

If I run my entire stored procedure in SQL Server and print @ReturnValue, I get 1 and the row is updated-

But when I call my stored from C#, I always get 0, and of course, the row didn't update.

What am I doing wrong ?

like image 236
Gonzalo.- Avatar asked Feb 24 '26 18:02

Gonzalo.-


1 Answers

Why are you doing all that work (declare, select, update conditionally) when you can just perform a conditional update?

ALTER PROCEDURE [dbo].[CheckLastEnvioListadoComprobanteEjercicio]
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.EnvioListadoEjercicioComprobantes 
    SET LastDate = GETDATE()
    WHERE LastDate <= DATEADD(HOUR, -1, GETDATE());

  IF @@ROWCOUNT > 0
    RETURN 1;
  ELSE
    RETURN 0;
END
GO

Anyway I don't think that's the way you deal with a return value. Try something like this (this is pseudo-code):

DatabaseDA.DefaultDb.ExecuteNonQuery(command);
var returnVal = command.Parameters.Add("@ReturnValue", SqlDbType.Int);
returnVal.Direction = ParameterDirection.ReturnValue; // this is important
DatabaseDA.DefaultDb.ExecuteNonQuery(command);
return Convert.ToBoolean(returnVal.Value);

Otherwise I suggest you stop using a return value for this, if you want the return parameter to be bit coming out of SQL Server, you can use an output parameter.

ALTER PROCEDURE [dbo].[CheckLastEnvioListadoComprobanteEjercicio]
  @ReturnVal BIT = 0 OUTPUT
AS
BEGIN
  SET NOCOUNT ON;

  UPDATE dbo.EnvioListadoEjercicioComprobantes 
    SET LastDate = GETDATE()
    WHERE LastDate <= DATEADD(HOUR, -1, GETDATE());

  SELECT @ReturnVal = @@ROWCOUNT;
END
GO

Now in your C# code (again, this is pseudo-code, I don't know that it will magically compile in your app if you copy and paste, but it should give you the idea):

SqlParameter rv = new SqlParameter("@ReturnVal", SqlDbType.Boolean);
rv.Direction=ParameterDirection.Output;
command.Parameters.Add(rv);
command.ExecuteNonQuery();
return Convert.ToBoolean(rv.Value);
like image 181
Aaron Bertrand Avatar answered Feb 27 '26 07:02

Aaron Bertrand



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!