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

时间:2015-05-08 17:49:07

标签: 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 = '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)

OLE DB提供程序&#34; MSDASQL&#34;对于链接服务器&#34; LinkedServerName&#34;返回消息&#34; [Sybase] [ODBC驱动程序] [SQL Anywhere]列&#39; AAA&#39;找不到&#34;。 Msg 7321,Level 16,State 2,Line 1 准备查询时发生错误&#34;

  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" 

针对OLE DB提供程序执行&#34; MSDASQL&#34;对于链接服务器&#34; LinkedServerName&#34;。

3 个答案:

答案 0 :(得分:5)

您需要在变量周围使用单引号,因为您尝试将它们设置为字符串文字。但同样复杂的是,您尝试在包含字符串中的另一个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代码。所以你需要双引号才能在你正在构建的主字符串中得到双引号。

答案 1 :(得分:0)

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

And cases.code IN (''' + @A +''', ''' + @B + ''')

答案 2 :(得分:0)

使用Brian Pressler响应我建议创建一个函数来格式化params,如果你有各种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

然后你可以在你的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)
相关问题