2009-08-12 30 views
6

Tôi muốn sử dụng một truy vấn như sau, tôi đang tìm kiếm thông tin chính xác/link để thoát khỏi chuỗiChuỗi Đúng Thoát cho xâu T-SQL

BOOKTITLE là nvarchar (200)

SELECT * FROM Sách WHERE BookTitle IN ('Mars and Venus', 'Stack''s Overflow \ r \ n')

Câu hỏi: Chỉ cần "'" thoát hoặc thậm chí \ r \ n cũng cần được thoát ? Nhà cung cấp MySql .Net đưa ra một phương thức để thoát khỏi các giá trị chuỗi, có chức năng nào như vậy trong Sql Server .Net Provider không?

Tôi có thể cần phải thoát C# tương đương cho các giá trị chuỗi.

Tôi biết về Parameterized Command, nhưng để giảm thiểu máy chủ của tôi để giao tiếp với khách hàng, và giá trị của tôi trong mệnh đề IN là từ 20 đến 50, nó trở nên quá nhiều mạng đắt tiền để chạy SELECT cho mỗi giá trị của BookTitle trong một cuộc gọi. Thay vì chạy truy vấn đơn lẻ và trả về tất cả các kết quả, cascaded giúp tiết kiệm tài nguyên mạng.

+0

Đây là nhận xét tiếp tuyến, nhưng vẫn quan trọng. Nếu bạn đang làm điều này cho các truy vấn của riêng bạn trong studio quản lý, đó là tốt. Nhưng nếu bạn đang thực hiện _programmatically_ — xây dựng chuỗi truy vấn của mình và thoát trong chương trình phía máy khách — _bạn đang làm sai. Bạn cần truy vấn được tham số hóa. –

+0

Đề xuất của bạn là bạn cần chạy 1 lựa chọn cho mỗi giá trị của thông số là không chính xác. Sử dụng một tham số bảng-giá trị hoặc XML HOẶC sử dụng một chuỗi phân cách bằng dấu phẩy và giải nén nó ở phía máy chủ SQL. Đó sẽ là một truy vấn. http://www.sommarskog.se/arrays-in-sql-2008.html – Davos

Trả lời

2

Có nhiều điều mà phải được thoát hơn là chỉ trích hoặc các ký tự dòng mới. Điều gì nếu có một đầu vào nhị phân (bởi hacker)? Sử dụng tốt hơn PreparedStatement (trong java) hoặc bất kỳ tương đương nào khác trong ngôn ngữ đích. mẫu 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

Mặc dù đây không phải là câu trả lời hoàn chỉnh, nhưng có, tôi đã thử điều tương tự trong C# với cách giải quyết ít và nó chấp nhận được cho bây giờ. –

5

Máy chủ SQL sẽ không nhận ra chuỗi \r\n, cho dù nó có được thoát hay không.

Bạn sẽ cần phải làm một cái gì đó như thế này thay vì nếu bạn muốn để phù hợp với \r\n trong BookTitle:

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

Có, tôi nhận được điều đó, nhưng tôi cần phải làm điều này trong C# động cho từng loại, như tôi sẽ cần một chuỗi thoát mà tôi có thể sử dụng chuỗi .replace cho tất cả các giá trị như vậy và chuẩn bị truy vấn cuối cùng. –

+0

Trong trường hợp đó, không sử dụng chuỗi thoát. Thay vào đó, hãy sử dụng truy vấn được tham số. – LukeH

0

Bạn có thể sử dụng các thông số giá trị bảng để vượt qua trong các giá trị cho tuyên bố IN. Nếu bạn không sử dụng phiên bản đủ mới của studio trực quan và/hoặc máy chủ sql để có quyền truy cập vào tham số giá trị bảng, thay vào đó bạn có thể chuyển vào một danh sách được phân tách bằng dấu phẩy dưới dạng tham số chuỗi rồi phân tích cú pháp tham số vào bảng. Có một số phương pháp để tách các chuỗi thành một biến bảng/bảng tạm thời. Bạn có thể google "chia chức năng trong máy chủ sql" cho một số tùy chọn.

0

Thông thường những gì tôi sẽ làm cho các tình huống như thế này, là chuyển thông tin của bạn như một tham số, nhưng trong XML, vì vậy bạn có thể làm một cái gì đó như thế này:

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 

trong trường hợp này, xml sẽ trông giống như '<ss><s>1</s><s>2</s>...etc...</ss>'

+0

CRLF sẽ không tồn tại trong quá trình xử lý xml, phải không? Vì nó được coi là khoảng trắng bạn phải thoát khỏi nó bằng cách nào đó. Làm cách nào để thoát khỏi CRLF trong Xml? Tôi đoán với CDATA, nhưng nó sẽ phát ra như thế nào trong truy vấn? – Cyberherbalist

+0

Tôi không tin rằng khoảng trống nói chung cần phải được thoát trong XML; nó chỉ là những gì nó là – John

2

Tôi đã gặp sự cố tương tự, nơi tôi cần có IN trong truy vấn chọn của mình và số lượng phần tử thay đổi theo thời gian chạy.

Tôi sử dụng truy vấn được tham số hóa dưới dạng thủ tục được lưu trữ và chuyển vào chuỗi được phân cách chứa danh sách những thứ tôi đang tìm kiếm. Việc thoát được tự động xử lý bởi hệ thống, không cần phải thực hiện các bước đặc biệt. Tốt hơn không làm cho nó được giới hạn bởi các ký tự sẽ được tìm thấy trong văn bản bạn đang tìm kiếm (như dấu phẩy). một thanh dọc ("|") có thể sẽ hoạt động tốt nhất trong nhiều trường hợp.

Nhân tiện, hãy đảm bảo rằng CRLF trong bảng của bạn là CHAR (13) + CHAR (10) vì ngược lại không phải là \ r \ n và bạn sẽ không tìm thấy nó nếu Environment.NewLine là một phần tìm kiếm của bạn.

Dưới đây là một thủ tục lưu trữ bằng cách sử dụng phân tích nhanh chóng và dơ bẩn giải quyết vào một bảng mà tôi đã sử dụng:

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) 

Đơn giản chỉ cần tạo danh sách các đầu sách như là một chuỗi đơn giản (có chứa bất cứ dấu nháy nhúng, CRLFs, và vv) và sử dụng truy vấn được tham số hóa. Tất nhiên, proc được lưu trữ của bạn có thể chứa những thứ khác ngoài danh sách được phân tách.

Các vấn đề liên quan