簡體   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