Sql-Server

動態查詢執行錯誤

  • May 8, 2020

我正在嘗試執行以下動態查詢程式碼:

 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');

這是我希望控制台在上述動態查詢的情況下輸出的內容,但是我遇到了錯誤。幫助!

  1. 您收到的錯誤是因為您end;的動態 SQL 版本中有一個不合適的尾隨(並且在有效的非動態版本中不存在):
end;' --> should be just '
  1. 您的動態 SQL 版本缺少所需數量的單引號(因此當您修復 1. 時,您仍然會有看起來像整數的日期)。
  2. 這似乎是一種更整潔的方法,主要是因為它避免了很多單引號意大利面、循環結構、重複轉換,並且更改分區數量只需要更改一個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;
  1. 避免像DD. 鍵入 需要額外的微秒時間DAY,但這樣做的好處是值得的:它使程式碼更加清晰和自我記錄,並避免為其他日期部分提供快捷方式,這可能會改變含義,從而改變結果(喜歡yw)。

引用自:https://dba.stackexchange.com/questions/115922