繁体   English   中英

如何正确地将DateTime从C#传递到SQL?

[英]How do I correctly pass DateTime from C# to SQL?

我正在尝试从C#运行存储过程,并且在单元测试时遇到转换错误。 我见过的这个问题的每个搜索结果都表明,使用ToString()不是传递DateTime的首选方法。

C#代码:

using (SqlConnection lvConn = new SqlConnection(gvSQLConnectionS))
{
    lvConn.Open();
    SqlCommand lvCmd = new SqlCommand(gvSQLsp, lvConn);
    lvCmd.CommandType = CommandType.StoredProcedure;
    lvCmd.Parameters.Add(new SqlParameter(gvSQLparamFunction, gvSQLfunctionUpdLE));
    lvCmd.Parameters.Add(new SqlParameter(gvSQLparamID, lvAAAID));
    lvCmd.Parameters.Add(new SqlParameter(gvSQLparamName, lvName));
    lvCmd.Parameters.Add(new SqlParameter(gvSQLparamPath, lvPath)); 
    SqlParameter lvParameterLE = lvCmd.Parameters.Add(gvSQLparamLE, SqlDbType.DateTime);
    SqlDateTime lvDTnow = new SqlDateTime(DateTime.Now);
    lvParameterLE.Value = lvDTnow;
    lvCmd.ExecuteNonQuery();
}

SQL安装程序:最后执行(日期时间,空)

存储过程:

ALTER PROCEDURE [dbo].[sp_BackupCleaner]
    @lvFunction int,
    @lvAAAID varchar(12) = NULL,
    @lvAAAID_new varchar(12) = NULL,
    @lvName varchar(35) = NULL,
    @lvName_new varchar(35) = NULL,
    @lvPath varchar(255) = NULL,
    @lvPath_new varchar(255) = NULL,
    @lvLastExecuted datetime = NULL
AS
BEGIN
    SET NOCOUNT ON;

    DECLARE @lvSQL varchar(max)    

IF @lvFunction = 6
    BEGIN
        SET @lvSQL = 'UPDATE [dbo].[Backup_Paths]
                SET [dbo].[Backup_Paths].[Last Executed] = '+@lvLastExecuted+'
                WHERE [dbo].[Backup_Paths].[AAA Client ID] = '''+@lvAAAID+'''
                AND [dbo].[Backup_Paths].[Process Name] = '''+@lvName+'''
                AND [dbo].[Backup_Paths].[UNC Path] = '''+@lvPath+''''
    END

execute(@lvSQL)
END

抛出异常:

System.Data.SqlClient.SqlException: Conversion failed when converting date and/or time from character string.

执行SET [dbo].[Backup_Paths].[Last Executed] = '+@lvLastExecuted+'就像在C#中使用.ToString()一样糟糕。

如果您不进一步动态修改@lvSQL ,则可以直接执行查询

IF @lvFunction = 6
BEGIN
    UPDATE [dbo].[Backup_Paths]
            SET [dbo].[Backup_Paths].[Last Executed] = @lvLastExecuted
            WHERE [dbo].[Backup_Paths].[AAA Client ID] = @lvAAAID 
            AND [dbo].[Backup_Paths].[Process Name] =  @lvName
            AND [dbo].[Backup_Paths].[UNC Path] = @lvPath
END

如果要进一步编辑查询,则需要使用sp_executesql并将参数转发到动态查询。

IF @lvFunction = 6
BEGIN
    SET @lvSQL = 'UPDATE [dbo].[Backup_Paths]
            SET [dbo].[Backup_Paths].[Last Executed] = @lvLastExecuted
            WHERE [dbo].[Backup_Paths].[AAA Client ID] = @lvAAAID
            AND [dbo].[Backup_Paths].[Process Name] = @lvName
            AND [dbo].[Backup_Paths].[UNC Path] = @lvPath'
END

SET @lvSQL = @lvSQL + ' WHERE [dbo].[Backup_Paths].SomeProp = 7'

execute sp_executesql @lvSQL, '@lvFunction int,
                               @lvECMID varchar(12),
                               @lvECMID_new varchar(12),
                               @lvName varchar(35),
                               @lvName_new varchar(35),
                               @lvPath varchar(255),
                               @lvPath_new varchar(255),
                               @lvLastExecuted datetime',
                      @lvFunction,
                      @lvECMID,
                      @lvECMID_new,
                      @lvName,
                      @lvName_new,
                      @lvPath,
                      @lvPath_new,
                      @lvLastExecuted;

无需使用动态SQL。 通常,应避免使用动态SQL。 很难找到不能用更好的东西代替动态SQL的情况。

只需编写并运行所需的语句即可:

IF @lvFunction = 6
    BEGIN
        UPDATE [dbo].[Backup_Paths]
            SET [dbo].[Backup_Paths].[Last Executed] = @lvLastExecuted
            WHERE [dbo].[Backup_Paths].[AAA Client ID] = @lvAAAID
            AND [dbo].[Backup_Paths].[Process Name] = @lvName
            AND [dbo].[Backup_Paths].[UNC Path] = @lvPath
    END

注意

如果存储过程执行许多不同的任务,则强烈表明应将其分解为单独的过程。

在此处输入图片说明 问题是尝试使用+运算符将Datetime变量与字符串文字连接起来。 如果您使用的是SqlServer 2012或更高版本,则可以使用CONCAT ,这样可以解决此问题。 (但当该值为NULL时,可能会使查询失败)

CONCAT('select blah blah blah', @myDateTimeValue);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM