Sql-Server
動態查詢執行錯誤
我正在嘗試執行以下動態查詢程式碼:
declare @sql nvarchar(max) set @sql = 'DECLARE @DatePartitionFunction nvarchar(max) = N''CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE RIGHT FOR VALUES (''; DECLARE @incremental_date nvarchar(150); select @incremental_date = '+CONVERT(VARCHAR(24),GETDATE(),112)+' declare @counter int = 0; WHILE @counter < 3 BEGIN SET @DatePartitionFunction += '''' + CONVERT(VARCHAR(24),DATEADD(DD, @counter, @incremental_date),112) + '''' + N'', ''; SET @counter += 1; END SET @DatePartitionFunction += '''' + CONVERT(VARCHAR(24),DATEADD(DD, @counter, @incremental_date),112) + '''' + N'');''; print (@DatePartitionFunction) end;' exec (@sql);
但是,它返回一個錯誤,說明語法不正確。
當我在動態查詢上下文之外執行相同的程式碼時,它會返回輸出。下面說的是動態查詢上下文之外的相同程式碼
DECLARE @DatePartitionFunction nvarchar(max) = N'CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE RIGHT FOR VALUES ('; DECLARE @incremental_date nvarchar(150); select @incremental_date = CONVERT(VARCHAR(24),GETDATE(),112) declare @counter int = 0; WHILE @counter < 3 BEGIN SET @DatePartitionFunction += '''' + CONVERT(VARCHAR(24),DATEADD(DD, @counter, @incremental_date),112) + '''' + N', '; SET @counter += 1; END SET @DatePartitionFunction += '''' + CONVERT(VARCHAR(24),DATEADD(DD, @counter, @incremental_date),112) + '''' + N');'; print (@DatePartitionFunction);
它產生所需的輸出文本,如下所示:
CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE RIGHT FOR VALUES ('20150923', '20150924', '20150925', '20150926');
這是我希望控制台在上述動態查詢的情況下輸出的內容,但是我遇到了錯誤。幫助!
- 您收到的錯誤是因為您
end;
的動態 SQL 版本中有一個不合適的尾隨(並且在有效的非動態版本中不存在):end;' --> should be just '
- 您的動態 SQL 版本缺少所需數量的單引號(因此當您修復 1. 時,您仍然會有看起來像整數的日期)。
- 這似乎是一種更整潔的方法,主要是因為它避免了很多單引號意大利面、循環結構、重複轉換,並且更改分區數量只需要更改一個
TOP()
參數:DECLARE @sql NVARCHAR(MAX) = N'CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE RIGHT FOR VALUES ('; ;WITH c(rn) AS ( SELECT TOP (4) CHAR(39) + CONVERT(CHAR(8), DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, GETDATE()), 112) + CHAR(39) FROM sys.all_columns ) SELECT @sql += STUFF((SELECT ',' + rn FROM c ORDER BY rn FOR XML PATH, TYPE).value(N'.[1]',N'varchar(max)'),1,1,''); SET @sql += N');'; PRINT @sql;
為什麼你需要將它嵌套在動態 SQL 中,我不確定,但你可以:
DECLARE @sql NVARCHAR(MAX) = N' DECLARE @pf NVARCHAR(MAX) = N''CREATE PARTITION FUNCTION DatePartitionFunction (datetime) AS RANGE RIGHT FOR VALUES (''; ;WITH c(rn) AS ( SELECT TOP (4) CHAR(39) + CONVERT(CHAR(8), DATEADD(DAY, ROW_NUMBER() OVER (ORDER BY name)-1, GETDATE()), 112) + CHAR(39) FROM sys.all_columns ) SELECT @pf += STUFF((SELECT '','' + rn FROM c ORDER BY rn FOR XML PATH, TYPE).value(N''.[1]'',N''varchar(max)''),1,1,''''); SET @pf += N'');''; PRINT @pf;'; EXEC sys.sp_executesql @sql;
- 請避免像
DD
. 鍵入 需要額外的微秒時間DAY
,但這樣做的好處是值得的:它使程式碼更加清晰和自我記錄,並避免為其他日期部分提供快捷方式,這可能會改變含義,從而改變結果(喜歡y
和w
)。