Tôi tin rằng có ba trường hợp khác nhau mà bạn phải lo lắng:
- chuỗi (bất kỳ thứ gì yêu cầu dấu ngoặc kép):
'''' + replace(@string, '''', '''''') + ''''
- tên (bất kỳ thứ gì không được phép sử dụng dấu ngoặc kép):
quotename(@string)
- những thứ không thể được trích dẫn:điều này yêu cầu đưa vào danh sách trắng
Lưu ý : Mọi thứ trong một biến chuỗi (char
, varchar
, nchar
, nvarchar
, v.v.) đến từ các nguồn do người dùng kiểm soát phải sử dụng một trong các phương pháp trên. Điều đó có nghĩa là ngay cả những thứ bạn mong đợi là số cũng được trích dẫn nếu chúng được lưu trữ trong các biến chuỗi.
Để biết thêm chi tiết, hãy xem Tạp chí Microsoft (Liên kết lỗi thời:2016-10-19) .
Đây là một ví dụ sử dụng cả ba phương pháp:
EXEC 'SELECT * FROM Employee WHERE Salary > ''' +
REPLACE(@salary, '''', '''''') + -- replacing quotes even for numeric data
''' ORDER BY ' + QUOTENAME(@sort_col) + ' ' + -- quoting a name
CASE @sort_dir WHEN 'DESC' THEN 'DESC' END -- whitelisting
Cũng lưu ý rằng bằng cách thực hiện tất cả các thao tác chuỗi nội tuyến trong EXEC
tuyên bố không có mối quan tâm với các vấn đề cắt ngắn. Nếu bạn gán kết quả trung gian cho các biến, bạn phải đảm bảo rằng các biến đủ lớn để giữ kết quả. Nếu bạn làm SET @result = QUOTENAME(@name)
bạn nên xác định @result
giữ ít nhất 258 (2 * 128 + 2) ký tự. Nếu bạn làm SET @result = REPLACE(@str, '''', '''''')
bạn nên xác định @result
có kích thước gấp đôi @str
(giả sử mọi ký tự trong @str
có thể là một câu trích dẫn). Và tất nhiên, biến chuỗi chứa câu lệnh SQL cuối cùng phải đủ lớn để chứa tất cả SQL tĩnh cộng với tất cả các biến kết quả.