【问题标题】:Escape single quote in openquery using dynamic query使用动态查询在openquery中转义单引号
【发布时间】:2015-07-19 17:25:14
【问题描述】:

我需要使用参数从链接服务器检索数据,例如@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)

链接服务器“LinkedServerName”的 OLE DB 提供程序“MSDASQL”返回消息“[Sybase][ODBC Driver][SQL Anywhere]Column 'AAA' not found”。 消息 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 case.code IN ('+ chr(39) + @A +', ' + chr(39)+ @B + chr(39)+ ') 怎么样
  • 它的行为与 (''' + @A +''', ''' + @B + ''') 相同。仍然给出“'AAA'附近的语法错误。”

标签: sql-server dynamic-sql linked-server openquery


【解决方案1】:

您需要在变量周围加上单引号,因为您试图将它们设为字符串文字。但更复杂的是,您试图在一个字符串中创建一个 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 代码。因此,您需要双双引号才能在您正在构建的主字符串中获得双引号。

【讨论】:

  • 这就是答案!非常感谢你,大脑。
  • 我的意思是使用@A 和@B 来转义单引号。在这种情况下,我可以简单地使用 case.code IN (''''AAA'''', ''''B'''') 。
【解决方案2】:

如果您有各种 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

然后你可以像这样在你的开放查询中使用它:

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)

【讨论】:

    【解决方案3】:

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

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

    【讨论】:

    • 那行不通。它返回错误:'AAA' 附近的语法不正确。
    • 当你得到错误时,当你 PRINT @Openquery+@TSQL 时你会得到什么?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 2018-08-01
    • 1970-01-01
    • 2014-12-24
    • 1970-01-01
    相关资源
    最近更新 更多