Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Escape single quote in openquery using dynamic query

I need to retrieve data from a linked server using a parameter, @PickedDate for example. The query works fine if I skip @A and @B, but it always returns an error due to a missing single quote. Please advise, thanks.

The query:

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 provider "MSDASQL" for linked server "LinkedServerName" returned message "[Sybase][ODBC Driver][SQL Anywhere]Column 'AAA' not found". Msg 7321, Level 16, State 2, Line 1 An error occurred while preparing the query "

  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" 

for execution against OLE DB provider "MSDASQL" for linked server "LinkedServerName".

like image 233
Weihui Guo Avatar asked May 08 '15 17:05

Weihui Guo


People also ask

How do you escape a single quote in SQL query string?

The simplest method to escape single quotes in SQL is to use two single quotes. For example, if you wanted to show the value O'Reilly, you would use two quotes in the middle instead of one. The single quote is the escape character in Oracle, SQL Server, MySQL, and PostgreSQL.

How do you escape a single quote in an inserted statement?

This means that to use it as part of your literal string data you need to escape the special character. With a single quote this is typically accomplished by doubling your quote. (Two single quote characters, not double-quote instead of a single quote.)

How do I escape a double quote in SQL Server?

If you need to use the double quote inside the string, you can use the backslash character. Notice how the backslash in the second line is used to escape the double quote characters. And the single quote can be used without a backslash.


2 Answers

You need single quotes around your variables since you are trying to make them string literals. But also complicating it is the fact that you are trying to create a SQL statement in a string that includes another SQL statement in a string. So you need to make your line read like:

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

You need two sets of double quotes so that the string literal inside of your string literal is interpreted correctly. Huh? Right. :)

Ultimately you need to build a string that has this valid SQL Syntax in it:

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')

You need two quotes around the AAA and BBB in your inner SQL string because it is also SQL code inside a string. So you need double double quotes to get double quotes inside your main string you are building.

like image 95
Brian Pressler Avatar answered Oct 18 '22 16:10

Brian Pressler


Using Brian Pressler response i suggest to create a function to format the params if you have various openquery calls, sometimes quoting a lot could be eyebreaker.

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

Then you can use it in your openqueries like this:

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)
like image 45
4D1C70 Avatar answered Oct 18 '22 15:10

4D1C70