2013-04-07 24 views
5

Tôi cố gắng chọn một số bản ghi đặc biệt chứa các ký tự đặc biệt nhưng SQL Server thay đổi các ký tự chuỗi của tôi trước khi chạy truy vấn.Máy chủ SQL đã thay đổi chuỗi của tôi trước khi chạy truy vấn

Ví dụ:

DECLARE @param NVARCHAR(30) 

    SET @param=N'¤÷þ'--this is my special string that i want to be searched exactly. 

    DECLARE @TSQL varchar(8000) 
    SET @TSQL = 'SELECT * FROM MyTable WHERE MyFieldName LIKE %' + @param + '% ' 

    PRINT @TSQL 

    --EXECUTE (@TSQL) 

Nhưng trong kết quả (in) Tôi thấy: (?)

SELECT * FROM MyTable WHERE MyFieldName LIKE '%¤÷þ?%' 

Như bạn thấy một số phần của chuỗi chuyển đổi sang nhân vật, vấn đề này gây SELECT của tôi lệnh trả về giá trị null.

Tôi cố gắng thay đổi collation của cơ sở dữ liệu mà tôi chạy truy vấn để:

SQL_Latin1_General_CP1_CI_AS 

Nó hoạt động tốt với một số chuỗi đặc biệt nhưng nó cũng không hỗ trợ tất cả các chuỗi của tôi. Vì vậy, câu hỏi là ở đây: làm thế nào tôi có thể nói với SQL Server, xin vui lòng không thay đổi mã ascii chuỗi của tôi? Có cách nào (hoặc bất kỳ đối chiếu nào) để nói SQL Server thấy chuỗi chính xác như trong thực tế không?

PS: Tôi đang sử dụng SQL Server 2008 R2.

+0

'MyFieldName' có loại nào? Thay đổi đối chiếu DB không làm gì với các cột hiện có, fyi. – usr

+2

Bạn mong đợi điều gì, '@ TSQL' là' varchar (8000) '? –

+0

OMG! Chỉ một phần mã của tôi được sao chép (tôi không bao giờ nghĩ về điều đó). – Jupiter

Trả lời

2

Nếu bạn có ký tự đặc biệt mà cần phải được bảo quản, sử dụng Unicode chuỗi kiểu NVARCHAR thay vì VARCHAR - nó là đơn giản .....

DECLARE @param NVARCHAR(30) 
SET @param = N'¤÷þ'--this is my special string that i want to be searched exactly. 

DECLARE @TSQL NVARCHAR(4000) -- <=== use NVARCHAR here 
SET @TSQL = N'SELECT * FROM MyTable WHERE MyFieldName LIKE %' + @param + N'% ' 

PRINT @TSQL 

Sau đó, các ký tự đặc biệt của bạn sẽ được giữ nguyên như đã nhập ....

Và như những người khác đã chỉ ra: ghép nối với nhau của bạn Các câu lệnh QL như thế này không bao giờ là một ý tưởng hay - nó mở ra mã của bạn cho các cuộc tấn công SQL injection tiềm ẩn. Bạn nên sử dụng truy vấn được tham số hóa và sp_executesql cho phép bạn xác định và cung cấp thông số cho truy vấn của mình.

+1

Cảm ơn câu trả lời đơn giản và cũng cho các mẹo bảo mật. (đây là một phần của mã của tôi chỉ cho mục đích thử nghiệm, Vì vậy, tôi sẽ thay đổi lệnh trong bản phát hành cuối cùng với các biến tham số.) – Jupiter

2
DECLARE @TSQL varchar(8000) 

varchar(8000) không thể đại diện ¤÷þ. Chỉ tiếp tục làm những gì bạn đang làm với @param; sử dụng một cái gì đó NVARCHAR dựa.

Khi usr chỉ ra chính xác, bạn thực sự nên sử dụng sp_executesql và khả năng xác định tham số. Từ các tài liệu:

DECLARE @IntVariable int; 
DECLARE @SQLString nvarchar(500); 
DECLARE @ParmDefinition nvarchar(500); 

/* Build the SQL string one time.*/ 
SET @SQLString = 
    N'SELECT BusinessEntityID, NationalIDNumber, JobTitle, LoginID 
     FROM AdventureWorks2012.HumanResources.Employee 
     WHERE BusinessEntityID = @BusinessEntityID'; 
SET @ParmDefinition = N'@BusinessEntityID tinyint'; 
/* Execute the string with the first parameter value. */ 
SET @IntVariable = 197; 
EXECUTE sp_executesql @SQLString, @ParmDefinition, 
         @BusinessEntityID = @IntVariable; 
+2

Ngoài ra, đừng làm điều ghép nối SQL. Sử dụng tham số với 'sp_executesql'. – usr

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