[英]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
注意
如果存储过程执行许多不同的任务,则强烈表明应将其分解为单独的过程。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.