2009-08-12 82 views
6

我想用一個查詢如下,我要尋找的確切信息/鏈接逃避串正確的字符串轉義爲T-SQL字符串文字

BOOKTITLE類型爲nvarchar(200)

SELECT * FROM圖書Where BookTitle IN('Mars and Venus','Stack'Overflow \ r \ n')

Question: 只有「'」需要轉義或甚至需要轉義? MySql .Net Provider公開了一種轉義字符串值的方法,Sql Server .Net Provider中是否有這樣的函數?

我可能需要C#相當於轉義字符串值。

我知道參數化命令,但爲了最大限度地減少我的服務器到客戶端的通信,並且我的IN子句中的值在20到50之間,因此對於每個BookTitle值運行SELECT在一個電話。而是運行單個查詢並返回級聯的所有結果有助於節省網絡資源。

+0

這是一條切線的評論,但仍然很重要。如果你在管理工作室爲你自己的查詢做這件事,那很好。但是,如果你正在做這個_programmatically_ —建立你的查詢字符串,並在客戶端程序— __你做錯wrong_。您需要參數化查詢。 – 2009-08-12 15:25:29

+0

你的建議,你需要運行1選擇參數的每個值是不正確的。使用Table-Valued-Parameter OR XML或使用逗號分隔字符串並在SQL Server端將其解壓縮。這將是一個查詢。 http://www.sommarskog.se/arrays-in-sql-2008.html – Davos 2014-02-18 01:46:56

回答

2

還有更多的東西,已經不僅僅是轉義引號或換行字符。如果有二進制輸入(黑客)怎麼辦?更好地使用PreparedStatement(在java中)或目標語言中的任何其他等價物。 Java示例:

PreparedStatement ps = con.prepareStatement("SELECT * FROM Books WHERE BookTitle IN (?, ?)"); 
ps.setString(1, "Mars and Venus"); 
ps.setString(2, "Stack's Overflow 
and 
"); 

ResultSet rs = ps.executeQuery(); 
.... 
+0

雖然這不是完整的答案,但是是的,我在c#中嘗試了類似的東西,沒有多少解決方法,現在可以接受。 – 2009-08-12 19:42:38

5

SQL Server將無法識別\r\n序列,無論是逃跑還是不行。

你需要做這樣的事情,而不是如果你想匹配\r\nBookTitle

-- \r = CHAR(13) 
-- \n = CHAR(10) 
SELECT * 
FROM Books 
WHERE BookTitle IN ('Mars and Venus', 'Stack''s Overflow ' + CHAR(13) + CHAR(10)) 
+0

是的我明白了,但我需要在C#中爲每種類型動態執行此操作,就像我需要一個可以使用字符串的轉義序列。替換所有這些值並準備最終查詢。 – 2009-08-12 15:25:40

+0

在這種情況下,請勿使用字符串轉義。改用參數化查詢。 – LukeH 2009-08-12 15:27:13

0

您可以使用表值參數來傳入IN語句的值。如果您沒有使用足夠新的visual studio和/或sql server版本來訪問表值參數,則可以傳入一個以逗號分隔的列表作爲字符串參數,然後將該參數解析爲表格。有幾種方法可以將字符串拆分爲臨時表/表變量。你可以谷歌「分割功能在SQL Server」幾個選項。

0

通常我會爲這樣的情況下做的,是通過您的信息作爲參數,但在XML中,所以你可以做這樣的事情:在這種情況下

DECLARE @iDoc INT 
EXEC sp_xml_preparedocument @iDoc OUTPUT, @MyXml 

SELECT 
    * 
FROM 
    MyTable 
WHERE 
    MyColumn IN (SELECT [Id] FROM OPENXML(@iDoc,'/ss/s',2) WITH ([Id] INT '.')) 

EXEC sp_xml_removedocument @iDoc 

,XML配置將看起來像'<ss><s>1</s><s>2</s>...etc...</ss>'

+0

CRLF不會在xml處理過程中倖存下來嗎?由於它被視爲空白,你不得不以某種方式逃避它。無論如何,你如何在Xml中逃避CRLF?我想用CDATA,但如何在查詢中發揮出來? – Cyberherbalist 2009-08-12 17:49:45

+0

我不認爲一般的空白需要在XML中轉義;它就是這樣 – John 2009-08-12 19:55:48

2

我碰到類似的問題,在這裏我需要在我的選擇查詢IN,並在運行時改變元素的數量。

我使用參數化查詢在存儲過程的形式,並通過包含的東西我要找的列表分隔字符串。逃生由系統自動處理,不需要採取非凡的步驟。最好不要使用您正在搜索的文本中的字符(如逗號)分隔它們。豎條(「|」)在許多情況下可能效果最好。

順便說一句,請確保您的表中的CRLFs是CHAR(13)+ CHAR(10),因爲相反的方法不是\ r \ n,並且如果Environment.NewLine是part的搜索。

下面是使用一個快速和骯髒的解析解析到一個表,我已經使用了一個存儲過程:

CREATE PROCEDURE FindBooks 
(
    @list varchar(500) 
) 
AS 

CREATE TABLE #parse_table (item varchar(500)) 

DECLARE @temp      VARCHAR(500) 
DECLARE @result      VARCHAR(500) 
DECLARE @str      VARCHAR(500) 
DECLARE @pos      SMALLINT 

SET @temp = RTRIM(LTRIM(@list)) 
SET @pos = 1 

WHILE @pos > 0 
    BEGIN 
    SET @pos = CHARINDEX('|',@temp) 
    IF @pos > 0 
     BEGIN 
     SET @result = SUBSTRING(@temp,1,@pos - 1) 
     SET @temp = RTRIM(LTRIM(SUBSTRING(@temp,@pos+1,LEN(@temp) - @pos))) 

     INSERT INTO #parse_table 
    SELECT @result 
     END 
    ELSE 
     INSERT INTO #parse_table 
     SELECT @temp 
END 

SELECT * FROM Books WHERE Title in (select * from #parse_table) 

只需創建您的書名的列表作爲一個簡單的字符串(含任何嵌入式單引號,CRLFs和等等)並使用參數化查詢。當然,您的存儲過程除了分隔列表外還可以包含其他內容。