正确的字符串转义为T-SQL字符串文字

时间:2009-08-12 15:17:54

标签: c# sql-server tsql

我想使用如下查询,我正在寻找转义字符串的确切信息/链接

BookTitle是NVARCHAR(200)

SELECT * FROM Books WHERE BookTitle IN('Mars and Venus','Stack'的溢出\ r \ n')

问题: 是否只需要转义“'”,甚至还需要转义\ r \ n? MySql .Net Provider公开了一个转义字符串值的方法,Sql Server .Net Provider中是否有这样的函数?

我可能需要C#等效转义为字符串值。

我知道参数化命令,但是为了最小化我的服务器到客户端的通信,并且IN子句中的值在20到50之间,对于BookTitle的每个值运行SELECT会变得太昂贵了。一个电话。而是运行单个查询并返回所有级联结果有助于节省网络资源。

5 个答案:

答案 0 :(得分:5)

SQL Server无法识别\r\n序列,无论它是否被转义。

如果您想匹配\r\n中的BookTitle,则需要执行此类操作:

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

答案 1 :(得分: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();
....

答案 2 :(得分:2)

我遇到了类似的问题,我需要在我的select查询中使用IN,并且元素的数量在运行时变化。

我以存储过程的形式使用参数化查询,并传入包含我正在寻找的事物列表的分隔字符串。转义由系统自动处理,无需采取特殊步骤。最好不要在你正在搜索的文本中找到的字符(如逗号)分隔。在许多情况下,垂直条(“|”)可能效果最好。

顺便说一下,确保表中的CRLF是CHAR(13)+ CHAR(10),因为相反的方式不是\ r \ n,如果Environment.NewLine是其中一部分,你就找不到它你的搜索。

这是一个存储过程,使用快速和脏解析解析为我使用过的表:

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)

只需将书名列表创建为一个简单的字符串(包含任何嵌入的撇号,CRLF等)并使用参数化查询。当然,您的存储过程可以包含除分隔列表之外的其他内容。

答案 3 :(得分:0)

您可以使用表值参数传入IN语句的值。如果您没有使用足够新版本的visual studio和/或sql server来访问表值参数,则可以将一个以逗号分隔的列表作为字符串参数传入,然后将该参数解析为表。有几种方法可以将字符串拆分为临时表/表变量。你可以谷歌“在SQL服务器中拆分功能”的几个选项。

答案 4 :(得分: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>'