3

我有一个在 SQL Server 中运行存储过程的应用程序,检查表中一行与getdate()

我从 c# 调用这个存储过程,并使用 a@returnValue来做一些事情

这是方法

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);
    }
}

这就是电话

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

然后在 SQL Server 中我有:

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 

EnvioListadoEjercicioComprobantes我有一个动作的 lastDate 行(ej 发送邮件)。

现在,我只有一排,2012-06-18 06:40:02.210有价值。我将此日期与实际日期进行比较,如果差异超过一个小时,则返回一点。

现在,在阿根廷,它大约2012-06-18 11:26

如果我getdate()在 SQL Server 中执行,我会得到2012-06-18 11:30:44.027

如果我在 SQL Server 中运行我的整个存储过程并 print @ReturnValue,我得到 1 并且该行被更新-

但是当我从 C# 调用我的存储时,我总是得到 0,当然,该行没有更新。

我究竟做错了什么 ?

4

3 回答 3

4

当您可以执行条件更新时,为什么还要执行所有这些工作(有条件地声明、选择、更新)?

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

无论如何,我认为这不是您处理返回值的方式。尝试这样的事情(这是伪代码):

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);

否则我建议您停止为此使用返回值,如果您希望返回参数有点来自 SQL Server,您可以使用输出参数。

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

现在在你的 C# 代码中(同样,这是伪代码,我不知道如果你复制和粘贴它会在你的应用程序中神奇地编译,但它应该给你这个想法):

SqlParameter rv = new SqlParameter("@ReturnVal", SqlDbType.Boolean);
rv.Direction=ParameterDirection.Output;
command.Parameters.Add(rv);
command.ExecuteNonQuery();
return Convert.ToBoolean(rv.Value);
于 2012-06-18T14:37:54.710 回答
0

检查数据库的排序规则设置:在 Select 语句中,您正在设置@returnValue但稍后您正在检查并返回@ReturnValue. 如果打开区分大小写,那是两个不同的变量。

于 2012-06-18T14:37:44.507 回答
0

尝试在存储过程的顶部添加 SET NOCOUNT ON ,传统上,返回值用于报告受影响的行数,使用“SET NOCOUNT ON”选项禁用此功能,这可能会导致返回值出现问题。

还要检查 SQL Server Logins Language 选项,因为这也会影响 DateTime 的计算方式(以及排序规则等其他内容)。可能是在 Management Studio 中,您正在使用使用阿根廷当地时间的 Windows 帐户进行连接,但 C# 应用程序正在使用美国/英语登录设置进行连接,这将导致 SQL Server 认为您处于不同的时区。

于 2012-06-18T14:43:21.503 回答