从 sp_executesql 的动态 SQL 字符串中的参数添加报价日期时间

Adding Quoted Datetimes from Paramaters in Dynamic SQL String for sp_executesql

我目前正在 SQL Server 2005 上工作,并尝试按如下方式构建动态查询:

DECLARE @GETDATE AS NVARCHAR(12);
DECLARE @GETDATE2 AS NVARCHAR(12);
SET @GETDATE = ...;
SET @GETDATE2 = ...;

SET @SQL =  
    'CREATE TABLE [dbo].[' + @TABLENAME + ']'
    +'(' 
    +'ShibNo' 'INT'
    +')' 
    +';'
    + CHAR(10) 
    +'INSERT INTO [dbo].[' + @TABLENAME + '] (ShibNo)'
    +'SELECT X.[ShibNo]'
    +'FROM'
    +'('
    +'SELECT'
    + 'I.[Shibno]'
    +',' + 'I.[ShibAzmnDate]'
    +',' + 'I.[ShibBeginTime]'
    +',' + 'I.[ShibEndTime]'
    +',' + 'I.[CarNum]'
    +',' + 'I.[DriverNo1]'
    +',' + 'I.[ShibKind]'
    +',' + 'I.[FStationID]'
    +',' + 'I.[LStationID]'
    +',' + 'I.[LineDetailRecordID]'
    +'FROM Inserted2 I'
    +'WHERE I.[ShibAzmnDate] BETWEEN ' + @GETDATE + ' AND ' + @GETDATE2 + 
    +'INTERCEPT'
    +'SELECT'
    + 'D.[Shibno]'
    +',' + 'D.[ShibAzmnDate]'
    +',' + 'D.[ShibBeginTime]'
    +',' + 'D.[ShibEndTime]'
    +',' + 'D.[CarNum]'
    +',' + 'D.[DriverNo1]'
    +',' + 'D.[ShibKind]'
    +',' + 'D.[FStationID]'
    +',' + 'D.[LStationID]'
    +',' + 'D.[LineDetailRecordID]'
    +'FROM Deleted2 D'
    +'WHERE D.[ShibAzmnDate] BETWEEN ' + @GETDATE + ' AND ' + @GETDATE2 + 
    +') AS X'
    +';'
;
EXECUTE sp_executesql @SQL
;

如您所见,查询字符串的WHERE子句中有一些参数,用于限制此处执行检查的日期范围。但是,当字符串作为使用 sp_executesql 的查询执行时,日期没有收到正确的撇号标点符号,这会产生错误。

我试过使用替换和转义字符,但显然不知道这样做的正确方法。我会很高兴(也很感激!)学习如何正确地做到这一点。

如果我检查查询的构建,则返回的字符串是以下变体之一:

' WHERE D.[ShibAzmnDate] BETWEEN ''03/13/2016'' AND ''03/14/2016'' '

' WHERE D.[ShibAzmnDate] BETWEEN 03/13/2016 AND 03/14/2016 '

' WHERE D.[ShibAzmnDate] BETWEEN ''''03/13/2016'''' AND ''''03/14/2016'''' '

等等...

有人可以帮助我了解如何正确构造此动态查询字符串(以及未来的动态查询字符串)以避免此问题吗?

非常非常感谢!

试试对我有用。

    DECLARE @DATE VARCHAR(250) = '2016-01-01', @VAR VARCHAR(MAX)

    SELECT @VAR = 'SELECT * FROM TABLE_A WHERE CREATE_DTE> '''+@DATE+''''

    SELECT @VAR

在查询中使用参数占位符,然后将参数的值传递给sp_executesql。有关详细信息,请参阅 https://msdn.microsoft.com/en-us/library/ms188001.aspx

DECLARE @GETDATE AS NVARCHAR(12);
DECLARE @GETDATE2 AS NVARCHAR(12);
SET @GETDATE = ...;
SET @GETDATE2 = ...;

SET @SQL =  
    'CREATE TABLE [dbo].[' + @TABLENAME + ']'
    +'(' 
    +'ShibNo' 'INT'
    +')' 
    +';'
    + CHAR(10) 
    +'INSERT INTO [dbo].[' + @TABLENAME + '] (ShibNo)'
    +'SELECT X.[ShibNo]'
    +'FROM'
    +'('
    +'SELECT'
    + 'I.[Shibno]'

    . . .

    +'FROM Inserted2 I'
    +'WHERE I.[ShibAzmnDate] BETWEEN @StartDate AND @EndDate' 
    +'INTERCEPT'
    +'SELECT'
    + 'D.[Shibno]'

    . . .

    +'FROM Deleted2 D'
    +'WHERE D.[ShibAzmnDate] BETWEEN @StartDate AND @EndDate'
    +') AS X'
    +';'
;
EXECUTE sp_executesql @SQL, N'@StartDate DATE, @EndDate DATE',
    @StartDate = @GETDATE, @EndDate = @GETDATE2
;

1 MSSQL 支持多行字符串文字,因此您不必分别连接每一行(不太明白为什么要将逗号连接为单独的文字)

2 由于您正在使用 sp_executesql 并且具有适当类型的变量,因此您在 sql 文本中不需要它们,也不必将它们转换为 varchar

SET @SQL =  
    cast('CREATE TABLE [dbo].[' as nvarchar(max)) + @TABLENAME + ']
    (
      ShibNo INT
    );

    INSERT INTO [dbo].[' + @TABLENAME + '] (ShibNo)
    SELECT X.[ShibNo]
    FROM
    (
      SELECT
         I.[Shibno]
        ,I.[ShibAzmnDate]
        ,I.[ShibBeginTime]
        ,I.[ShibEndTime]
        ,I.[CarNum]
        ,I.[DriverNo1]
        ,I.[ShibKind]
        ,I.[FStationID]
        ,I.[LStationID]
        ,I.[LineDetailRecordID]
      FROM Inserted2 I
      WHERE I.[ShibAzmnDate] BETWEEN @date1 AND @date2
      INTERCEPT
      SELECT
         D.[Shibno]
        ,D.[ShibAzmnDate]
        ,D.[ShibBeginTime]
        ,D.[ShibEndTime]
        ,D.[CarNum]
        ,D.[DriverNo1]
        ,D.[ShibKind]
        ,D.[FStationID]
        ,D.[LStationID]
        ,D.[LineDetailRecordID]
      FROM Deleted2 D
      WHERE D.[ShibAzmnDate] BETWEEN @date1 AND @date2
    ) AS X'

EXECUTE sp_executesql @SQL, N'@date1 datetime, @date2 datetime', @getdate, @getdate2;