[英]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.