2009-08-12 81 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和等等)并使用参数化查询。当然,您的存储过程除了分隔列表外还可以包含其他内容。