我有以下查詢:
DECLARE @periodEnd datetime = '2021-12-09 02:41:42.000'
DECLARE @ID VARCHAR(50) = '35915D4B-E210-48C0-ADD5-C68AAEB62C36'
EXEC('SELECT COUNT(*) AS count FROM pageloads nolock WHERE domainId = ''' @ID ''' AND paid = 1 AND source IN (2) AND clickedOn BETWEEN DATEADD(MONTH, -3,' @periodEnd ') AND ' @periodEnd)
但我收到一個錯誤:
'9' 附近的語法不正確。
uj5u.com熱心網友回復:
這里不需要動態 SQL。您擁有的實際代碼也不會產生該錯誤;它可能會產生此錯誤:
訊息 241,級別 16,狀態 1,第 4 行
從字串轉換日期和/或時間時轉換失敗
這是因為您將value 添加'select...MONTH, -3,'到datetimevalue 2021-12-09T02:41:42.000;顯然前者是無效的datetime并且轉換失敗。
使用引數化的非動態陳述句,你不會得到任何錯誤。
DECLARE @periodEnd datetime = '2021-12-09T02:41:42.000'; -- Use an unambiguous datetime format
DECLARE @ID uniqueidentifier = '35915D4B-E210-48C0-ADD5-C68AAEB62C36'; --This is clearly a GUID, so use the right data type.
SELECT COUNT(*) AS count
FROM dbo.pageloads pl --nolock is an odd alias. I've gone for a better one.
WHERE domainId = @ID
AND paid = 1
AND source IN (2) --Why IN when you only supply one value?
AND clickedOn BETWEEN DATEADD(MONTH, -3, @periodEnd) AND @periodEnd;
另請注意,這BETWEEN可能沒有按照您的預期進行。對于上述情況,這將有效地解決以下問題:
AND clickedOn >= '2021-09-09T02:41:42.000'
AND clickedOn <= '2021-12-09T02:41:42.000'
大多數時候,我看到人們使用這種邏輯BETWEEN來排除時間>=和<邏輯。雖然我不會猜測這就是你想要的。
uj5u.com熱心網友回復:
您只是在日期變數周圍缺少一些單引號。由于您是在動態 SQL 中構建查詢,因此您的日期作為日期文字傳遞到動態查詢中,因此它們需要在它們周圍加上單引號。
要在動態 SQL 中表示單引號,您實際上需要 3 個單引號,正如您在 @ID 變數周圍已有的那樣。最后,您需要 4 個單引號將單引號添加到動態中并終止 EXEC 字串。
所以它看起來像這樣:
DECLARE @periodEnd datetime = '2021-12-09 02:41:42.000'
DECLARE @ID VARCHAR(50) = '35915D4B-E210-48C0-ADD5-C68AAEB62C36'
EXEC('SELECT COUNT(*) AS count FROM pageloads nolock WHERE domainId = ''' @ID ''' AND paid = 1 AND source IN (2) AND clickedOn BETWEEN DATEADD(MONTH, -3,''' @periodEnd ''') AND ''' @periodEnd '''')
每當我將變數傳遞給動態 SQL 時,我總是會得到像這樣的單引號亂七八糟的代碼。
看起來您正在嘗試使用 WITH(NOLOCK) 表提示來加快行程并防止在運行此計數時對性能產生任何影響,這是一個好主意。你會在這個網站上收到很多關于使用 WITH(NOLOCK) 的反對意見,但不是來自我。對于這種型別的查詢,這是一個非常有用的功能,您需要一個快速的數字,并且不想在獲得它時將您的日志記錄程序停止。
使用 WITH(NOLOCK) 的正確語法是:
DECLARE @periodEnd datetime = '2021-12-09 02:41:42.000'
DECLARE @ID VARCHAR(50) = '35915D4B-E210-48C0-ADD5-C68AAEB62C36'
EXEC('SELECT COUNT(*) AS count FROM pageloads pl WITH(NOLOCK) WHERE domainId = ''' @ID ''' AND paid = 1 AND source IN (2) AND clickedOn BETWEEN DATEADD(MONTH, -3,''' @periodEnd ''') AND ''' @periodEnd '''')
以前您使用“nolock”作為表別名,這不是一個好主意。我將表別名更改為“pl”。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/407734.html
標籤:
