2015-05-08 4 views
4

Мне нужно получить данные с связанного сервера с помощью параметра @PickedDate, например. Запрос работает отлично, если я пропускаю @A и @B, но он всегда возвращает ошибку из-за отсутствия отдельной кавычки. Пожалуйста, посоветуйте, спасибо.Escape single quote в 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 (' + @A +', ' + @B + ') 
      ORDER BY casenum'')' 
Exec (@[email protected]) 

OLE DB провайдер "MSDASQL" для связанного сервера "LinkedServerName" возвращается сообщение "[Sybase] [ODBC Driver] [SQL Anywhere] Колонка 'AAA' не найден". Msg 7321, Level 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" 

для выполнения с OLE DB провайдера "MSDASQL" для связанного сервера "LinkedServerName" произошла ошибка.

+0

как насчет А cases.code IN ('+ CHR (39) + @A +', '+ CHR (39) + @B + chr (39) + ') – xQbert

+0

'char (39)' http://stackoverflow.com/questions/14657056/how-do-i-use-char39-in-a-sql-statement-where- пункт – xQbert

+0

Он ведет себя так же, как ('' '+ @A +' '', '' '+ @B +' ''). Все еще дает «Неправильный синтаксис рядом с« AAA »». – Zerubbabel

ответ

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, потому что это также SQL код внутри строка. Поэтому вам нужны двойные двойные кавычки, чтобы получить двойные кавычки внутри вашей основной строки, которую вы строите.

+0

Это ответ! Большое спасибо, Мозг. – Zerubbabel

+0

Я хотел использовать @A и @B, чтобы избежать одиночных кавычек. В этом случае я могу просто использовать case.code IN ('' '' AAA '' '', '' '' B '' ''). – Zerubbabel

0

Вам нужно ., чтобы добавить одиночные кавычки таким образом они будут появляться в динамическом контексте запроса Попробуйте изменить эту строку следующим образом:

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

Это не работает. Он возвращает ошибку: неправильный синтаксис рядом с «AAA». – Zerubbabel

+0

Когда вы получаете сообщение об ошибке, что вы получаете, когда используете PRINT @ Openquery + @ TSQL? –

0

Используя ответ Брайана Пресслера, я предлагаю создать функцию для форматирования параметров, если у вас есть различные вызовы 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 [email protected] 
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 (@[email protected])