2013-03-14 66 views
14

我試圖執行以下語句,以逃避單引號(即使用兩個單引號):逃逸單引號在SQL Server

declare @year varchar(max) 
set @year = '111,11'; 
exec ('SELECT * FROM SplitValues(' + @year + ','','')'); 

我甚至試過用char(39)代替報價:

declare @year varchar(max) 
set @year = '111,11'; 
exec ('SELECT * FROM SplitValues(' + @year + ',' + char(39) + ',' + char(39) + ')'); 

但它沒有幫助。這是我在這個網站上找到的唯一兩個解決方案。任何幫助?

這是簡化的查詢清理你所有的問題:

declare @year varchar(max) 
set @year = '111,11'; 
SELECT * FROM SplitValues(@year , ',') 

我要做到這一點,但使用動態查詢。

+0

爲什麼你需要在這裏使用EXEC? – Bridge 2013-03-14 12:19:39

+0

這是因爲我現在工作的查詢非常複雜,無法在此處發佈。這只是我想要做的一瞥。 – Saksham 2013-03-14 12:24:23

+0

可能的重複* [在SQL Server中替換單引號](http://stackoverflow.com/questions/1440733/replace-single-quotes-in-sql-server)*。 – 2016-01-25 14:50:13

回答

23

一句忠告。測試動態腳本時,首先顯示它而不是執行它。這樣,您將能夠完全看到EXEC聲明中的情況。

現在到了這個問題。您應該記住,您未將變量改爲SplitValues,而是將該變量的值連接到腳本中。由於值爲varchar,因此應將其與其周圍的引號連接起來。他們的缺席是唯一的問題。

第二個參數(逗號)周圍的引號在兩種情況下均正確轉義。所以,僅僅使用兩種方法來添加引號的第一個參數:

DECLARE @year varchar(max), @sql varchar(max); 
SET @year = '111,11'; 
SET @sql = 'SELECT * FROM SplitValues(''' + @year + ''','','')'; 
SELECT @sql; 
  • 使用CHAR(39)

    • 引號的重複

      DECLARE @year varchar(max), @sql varchar(max); 
      SET @year = '111,11'; 
      SET @sql = 'SELECT * FROM SplitValues(' + CHAR(39) + @year + CHAR(39) + ',' + CHAR(39) + ',' + CHAR(39) + ')'; 
      SELECT @sql; 
      

    顯然,第一種方法更加緊湊,但正如我所說的,兩者都很好,因爲this SQL Fiddle demo清楚地表明。

    但是,請注意,如果您原諒雙關語,您可以輕鬆地擺脫此問題。您可以使用EXEC sp_executesql而不是EXEC(),它允許您使用參數。下面是重寫使用sp_executesql相同的腳本:

    DECLARE @year varchar(max), @delim char(1); 
    SET @year = '111,11'; 
    SET @delim = ','; 
    EXEC sp_executesql 
        N'SELECT * FROM SplitValues(@year_param,@delim_param)', 
        N'@year_param varchar(max), @delim_param char(1)', 
        @year,@delim; 
    

    正如你所看到的,沒有必要擔心轉義引號:SQL Server會正確替換值,而不是你的麻煩。

  • +0

    對不起,我不確定我懂不懂。你在這裏觀察到的問題是什麼? – 2013-11-26 12:57:51

    +0

    我想在您的初始聲明中指出您應該打印命令而不是執行驗證的諷刺,但sp_executesql不會給您打印語句而不執行它的選項。如果有辦法,也許你應該展示它。 我想打印出來的聲明是有限的實用程序,因爲它比替代品更具可讀性。 – 2013-11-27 00:58:14

    +0

    如果動態查詢不包含任何名稱參數化(在這種情況下沒有任何名稱參數),則不需要將許多部分粘在一起構建。所以是的,使用一個變量來存儲查詢只是在/之前打印它而不是它的執行似乎沒有多大價值。 – 2013-11-27 04:41:18

    8

    只需鍵入單引號兩次:

    select 'that''s it' 
    
    +0

    這是我嘗試的第一件事,你可以在我的發佈解決方案中看到。 – Saksham 2013-03-14 12:18:48

    +1

    不完全。 '+ char(39)+'會​​給你三個引號,而你需要四個引號。讓我們試試整個語句: exec('SELECT * FROM SplitValues('''+ @year +''','''','''')'); – 2013-03-14 12:22:19

    2

    好了......你想利用這個字符串:

    SELECT * FROM SplitValues(@year , ',') 
    

    ,使它像這樣的字符串:

    'SELECT * FROM SplitValues('111,11' , '','')' 
    

    所以,你的最終代碼是:

    declare @year varchar(max), @sql varchar(max) 
    set @year = '111,11'; 
    set @sql = 'SELECT * FROM SplitValues(''' + @year + ''' , '''','''')' 
    
    select @sql 
    

    其實,最後選擇你會用exec()來代替。不過,你可能應該使用sp_sqlexecute這樣的東西,因爲你可以使用參數化查詢。