Sql server 使用动态查询在openquery中转义单引号

Sql server 使用动态查询在openquery中转义单引号,sql-server,dynamic-sql,linked-server,openquery,Sql Server,Dynamic Sql,Linked Server,Openquery,我需要使用参数@PickedDate从链接服务器检索数据。如果我跳过@A和@B,查询工作正常,但由于缺少一个引号,它总是返回一个错误。请告知,谢谢 查询: Declare @OPENQUERY nvarchar(500), @TSQL nvarchar(max), @LinkedServer nvarchar(20), @A varchar(5), @B varchar(5), @PickedDate varchar(8) Set @PickedDate = '20150501' Set @A

我需要使用参数@PickedDate从链接服务器检索数据。如果我跳过@A和@B,查询工作正常,但由于缺少一个引号,它总是返回一个错误。请告知,谢谢

查询:

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)
声明@OPENQUERY-nvarchar(500),@TSQL-nvarchar(max),@LinkedServer-nvarchar(20),@A-varchar(5),@B-varchar(5),@PickedDate-varchar(8)
设置@PickeDate='20150501'
设置@A='AAA'
Set@B='BBB'
Set@LinkedServer='LinkedServerName'
Set@OPENQUERY='从OPENQUERY(+@LinkedServer+),''中选择*
Set@TSQL='选择cases.casenum、user.username、code
从案例
内部联接用户
在cases.casenum=user.user\u id上
其中cases.date_opened>DateAdd(day,1-datepart(dw,Convert(date,“++@PickedDate+”)),Convert(date,“++@PickedDate+”))

和cases.date_opened您需要添加单引号,以便它们显示在动态查询上下文中。请尝试将该行更改为:

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')
Select*fromOpenQuery(LinkedServerName,'Select cases.casenum,user.username,code
从案例
内部联接用户
在cases.casenum=user.user\u id上
其中cases.date_opened>DateAdd(day,1-datepart(dw,Convert(date,20150501)),Convert(date,20150501))

和cases.date_open使用Brian Pressler response,我建议创建一个函数来格式化参数,如果您有各种openquery调用,有时引用很多可能会让人目瞪口呆

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
然后您可以在OpenQuery中使用它,如下所示:

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)
声明@OPENQUERY-nvarchar(500),@TSQL-nvarchar(max),@LinkedServer-nvarchar(20),@A-varchar(5),@B-varchar(5),@PickedDate-varchar(8)
设置@PickeDate='20150501'
设置@A='AAA'
Set@B='BBB'
Set@LinkedServer='LinkedServerName'
Set@OPENQUERY='从OPENQUERY(+@LinkedServer+),''中选择*
Set@TSQL='选择cases.casenum、user.username、code
从案例
内部联接用户
在cases.casenum=user.user\u id上
其中cases.date_opened>DateAdd(day,1-datepart(dw,Convert(date,“++@PickedDate+”)),Convert(date,“++@PickedDate+”))

和cases.date_打开时不起作用。它返回错误:“AAA”附近的语法不正确。当您收到错误时,当您打印@Openquery++@TSQL时会得到什么?和cases.code IN(“+chr(39)+@A+”,“+chr(39)+@B+chr(39)+”
char(39)
的行为与(“++@A+”,“++@B+”)相同。仍然给出“AAA附近的语法不正确。”这就是答案!非常感谢你,布莱恩。我想用@A和@B来转义单引号。在这种情况下,我可以简单地使用cases.code In('AAA','B'))。
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)