我正在尝试从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安装程序: 上次执行(datetime,null)
存储过程:
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.
答案 0 :(得分:3)
执行SET SHOWPLAN_XML OFF;
时与在C#中使用SET [dbo].[Backup_Paths].[Last Executed] = '+@lvLastExecuted+'
一样糟糕。
如果您没有进一步动态修改.ToString()
,您可以直接执行查询
@lvSQL
如果您要进一步编辑查询,则需要使用sp_executesql
并将参数转发到动态查询。
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
答案 1 :(得分:1)
无需使用动态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
注意强>
如果存储过程执行许多不同的任务,那么强烈的迹象表明它应该分解为单独的过程。
答案 2 :(得分:-1)