使用动态查询在 openquery 中转义单引号
Escape single quote in openquery using dynamic query
我需要使用参数从链接服务器检索数据,例如@PickedDate。如果我跳过@A 和@B,查询工作正常,但由于缺少单引号,它总是 returns 错误。请指教,谢谢
查询:
Declare @OPENQUERY nvarchar(500), @TSQL nvarchar(max), @LinkedServer nvarchar(20), @A varchar(5), @B varchar(5), @PickedDate varchar(8)
Set @PickedDate = '20150501'
Set @A = 'AAA'
Set @B = 'BBB'
Set @LinkedServer = 'LinkedServerName'
Set @OPENQUERY = 'Select * From Openquery('+ @LinkedServer + ','''
Set @TSQL = 'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.code IN (' + @A +', ' + @B + ')
ORDER BY casenum'')'
Exec (@Openquery+@TSQL)
链接服务器 "LinkedServerName" 的 OLE DB 提供程序 "MSDASQL" 返回消息“[Sybase][ODBC 驱动程序][SQL 任何地方] 列 'AAA' 未找到”。
消息 7321,级别 16,状态 2,第 1 行
准备查询“
时出错
SELECT cases.casenum, username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened >
DateAdd(day,1-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.date_opened <=
DateAdd(day,8-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.code IN (AAA, BBB)
ORDER BY casenum"
针对链接服务器 "LinkedServerName" 的 OLE DB 提供程序 "MSDASQL" 执行。
您需要添加单引号,以便它们出现在动态查询上下文中。尝试将该行更改为:
And cases.code IN (''' + @A +''', ''' + @B + ''')
您需要在变量周围加上单引号,因为您正试图使它们成为字符串文字。但也使它复杂化的是,您正试图在一个字符串中创建一个 SQL 语句,该字符串中包含另一个 SQL 语句。所以你需要让你的行看起来像:
And cases.code IN (''''' + @A +''''', ''''' + @B + ''''')
您需要两组双引号,以便正确解释字符串文字中的字符串文字。嗯?正确的。 :)
最终您需要构建一个包含此有效 SQL 语法的字符串:
Select * From Openquery(LinkedServerName,'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.code IN (''AAA'', ''BBB'')
ORDER BY casenum')
您的内部 SQL 字符串中的 AAA 和 BBB 需要两个引号,因为它也是字符串中的 SQL 代码。所以你需要双引号才能在你正在构建的主字符串中得到双引号。
如果您有各种 openquery 调用,我建议使用 Brian Pressler 响应创建一个函数来格式化参数,有时引用很多可能会让人大开眼界。
CREATE FUNCTION [dbo].[Ufn_QuoteFormat]
( @param varchar(200) --Modify accord your requirement)
RETURNS varchar(208)
AS
BEGIN
DECLARE @SingleQuote char(1) = CHAR(39)
RETURN @SingleQuote + @SingleQuote + @param + @SingleQuote +@SingleQuote
END
然后你可以像这样在你的 openqueries 中使用它:
Declare @OPENQUERY nvarchar(500), @TSQL nvarchar(max), @LinkedServer nvarchar(20), @A varchar(5), @B varchar(5), @PickedDate varchar(8)
Set @PickedDate = '20150501'
Set @A = 'AAA'
Set @B = 'BBB'
Set @LinkedServer = 'LinkedServerName'
Set @OPENQUERY = 'Select * From Openquery('+ @LinkedServer + ','''
Set @TSQL = 'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.code IN (' + [dbo].[Ufn_QuoteFormat](@A) +', ' + [dbo].[Ufn_QuoteFormat](@B) + ')
ORDER BY casenum'')'
Exec (@Openquery+@TSQL)
我需要使用参数从链接服务器检索数据,例如@PickedDate。如果我跳过@A 和@B,查询工作正常,但由于缺少单引号,它总是 returns 错误。请指教,谢谢
查询:
Declare @OPENQUERY nvarchar(500), @TSQL nvarchar(max), @LinkedServer nvarchar(20), @A varchar(5), @B varchar(5), @PickedDate varchar(8)
Set @PickedDate = '20150501'
Set @A = 'AAA'
Set @B = 'BBB'
Set @LinkedServer = 'LinkedServerName'
Set @OPENQUERY = 'Select * From Openquery('+ @LinkedServer + ','''
Set @TSQL = 'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.code IN (' + @A +', ' + @B + ')
ORDER BY casenum'')'
Exec (@Openquery+@TSQL)
链接服务器 "LinkedServerName" 的 OLE DB 提供程序 "MSDASQL" 返回消息“[Sybase][ODBC 驱动程序][SQL 任何地方] 列 'AAA' 未找到”。 消息 7321,级别 16,状态 2,第 1 行 准备查询“
时出错 SELECT cases.casenum, username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened >
DateAdd(day,1-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.date_opened <=
DateAdd(day,8-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.code IN (AAA, BBB)
ORDER BY casenum"
针对链接服务器 "LinkedServerName" 的 OLE DB 提供程序 "MSDASQL" 执行。
您需要添加单引号,以便它们出现在动态查询上下文中。尝试将该行更改为:
And cases.code IN (''' + @A +''', ''' + @B + ''')
您需要在变量周围加上单引号,因为您正试图使它们成为字符串文字。但也使它复杂化的是,您正试图在一个字符串中创建一个 SQL 语句,该字符串中包含另一个 SQL 语句。所以你需要让你的行看起来像:
And cases.code IN (''''' + @A +''''', ''''' + @B + ''''')
您需要两组双引号,以便正确解释字符串文字中的字符串文字。嗯?正确的。 :)
最终您需要构建一个包含此有效 SQL 语法的字符串:
Select * From Openquery(LinkedServerName,'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,20150501)), Convert(date,20150501))
And cases.code IN (''AAA'', ''BBB'')
ORDER BY casenum')
您的内部 SQL 字符串中的 AAA 和 BBB 需要两个引号,因为它也是字符串中的 SQL 代码。所以你需要双引号才能在你正在构建的主字符串中得到双引号。
如果您有各种 openquery 调用,我建议使用 Brian Pressler 响应创建一个函数来格式化参数,有时引用很多可能会让人大开眼界。
CREATE FUNCTION [dbo].[Ufn_QuoteFormat]
( @param varchar(200) --Modify accord your requirement)
RETURNS varchar(208)
AS
BEGIN
DECLARE @SingleQuote char(1) = CHAR(39)
RETURN @SingleQuote + @SingleQuote + @param + @SingleQuote +@SingleQuote
END
然后你可以像这样在你的 openqueries 中使用它:
Declare @OPENQUERY nvarchar(500), @TSQL nvarchar(max), @LinkedServer nvarchar(20), @A varchar(5), @B varchar(5), @PickedDate varchar(8)
Set @PickedDate = '20150501'
Set @A = 'AAA'
Set @B = 'BBB'
Set @LinkedServer = 'LinkedServerName'
Set @OPENQUERY = 'Select * From Openquery('+ @LinkedServer + ','''
Set @TSQL = 'SELECT cases.casenum, user.username, code
From cases
Inner join user
On cases.casenum = user.user_id
Where cases.date_opened > DateAdd(day,1-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.date_opened <= DateAdd(day,8-datepart(dw,Convert(date,' + @PickedDate + ')), Convert(date,' + @PickedDate + '))
And cases.code IN (' + [dbo].[Ufn_QuoteFormat](@A) +', ' + [dbo].[Ufn_QuoteFormat](@B) + ')
ORDER BY casenum'')'
Exec (@Openquery+@TSQL)