从 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;
我目前正在 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;