Làm thế nào để? Tham số và câu lệnh LIKE SQL


80

Tôi đang viết một hàm tìm kiếm và đã nghĩ ra truy vấn này bằng cách sử dụng các tham số để ngăn chặn, hoặc ít nhất là hạn chế các cuộc tấn công SQL injection. Tuy nhiên, khi tôi chạy nó qua chương trình của mình, nó không trả về bất cứ điều gì:

SELECT * FROM compliance_corner WHERE (body LIKE '%@query%') OR (title LIKE '%@query%')

Các tham số có thể được sử dụng như thế này không? hoặc chúng chỉ hợp lệ trong một trường hợp như:

SELECT * FROM compliance_corner WHERE body LIKE '%<string>%'( <string>đối tượng tìm kiếm ở đâu).

EDIT: Tôi đang xây dựng hàm này bằng VB.NET, điều đó có ảnh hưởng đến cú pháp mà các bạn đã đóng góp không?

Ngoài ra, tôi đã chạy câu lệnh này trong SQL Server: SELECT * FROM compliance_corner WHERE (body LIKE '%max%') OR (title LIKE% max% ') `và điều đó trả về kết quả.

Câu trả lời:


78

Mã cơ bản trực quan của bạn sẽ trông giống như sau:

Dim cmd as New SqlCommand("SELECT * FROM compliance_corner WHERE (body LIKE '%' + @query + '%') OR (title LIKE '%' + @query + '%')")

cmd.Parameters.Add("@query", searchString)

3
Như Adam đã chỉ ra trong câu trả lời của mình, điều này không bảo vệ khỏi việc tiêm SQL. Truy vấn phải được tham số hóa.
DOK

6
Bạn có thể cung cấp một ví dụ mà điều này không ngăn chặn việc tiêm SQL? Từ thử nghiệm của tôi, nó hoạt động tốt
John

27
Nó không mở để SQLtiêm, chỉ LIKEtiêm. Điều này có nghĩa người dùng có thể nhập các ký tự đặc biệt như % ^_đó LIKEsẽ giải thích đặc biệt. Điều này có nghĩa là người dùng có thể không nhận được những gì họ mong đợi cho các tìm kiếm nhất định. Ví dụ, một tìm kiếm 'less than 1% fat'có thể trả về kết quả 'less than 1% of doctors recommend this - it's full of fat!'.
Alex Humphrey

1
Tôi đồng ý, lượt thích là tùy thuộc vào "Like Injection" và tác hại chỉ là người dùng không nhận được những gì họ mong đợi. Vệ sinh truy vấn nên được thực hiện mọi lúc ngay cả khi được tham số hóa. Chỉ dựa vào sự bảo vệ đó là không an toàn chính xác.
Anthony Mason

1
Tôi cũng khuyên bạn nên làm searchString.Replace("[","[[]").Replace("%","[%]").Replace("_","[_]"), điều này sẽ thích tiêm LIKE (miễn là bạn không sử dụng mệnh đề thoát).
8DX

114

Vâng, tôi sẽ đi với:

 Dim cmd as New SqlCommand(
 "SELECT * FROM compliance_corner"_
  + " WHERE (body LIKE @query )"_ 
  + " OR (title LIKE @query)")

 cmd.Parameters.Add("@query", "%" +searchString +"%")

Điều này đúng, câu trả lời được chấp nhận do John cung cấp có cú pháp sai!
Adam

3
Tôi không chắc cú pháp của anh ấy không chính xác như thế nào, giải pháp của anh ấy hoạt động tốt. Tôi có một hàm tạo và trả về một câu lệnh SQL để sử dụng trong một cơ sở dữ liệu hoặc bất cứ thứ gì khác.
Anders

1
Lưu ý bổ sung: Cú pháp cho C # sử dụng MySQLDataAdapter = da = new MySQLDataAdapter ("CHỌN * TỪ tableA WHERE fieldA = @fieldA"); da.SelectCommand.Parameters.AddWithValue ("@ fieldA", "%" + someValue + "%");
John M

3
Câu trả lời khác (từ John) cũng hoạt động, nhưng thực sự rất dễ bị giống như tiêm, mà MIGHT cho kết quả kỳ lạ, tùy thuộc vào mục đích lĩnh vực của bạn.
Steven Lemmens

1
Không nên cmd.Parameters.Addtrở thành cmdLoad.Parameters.AddWithValuehoặc có bất kỳ vấn đề? Tôi hiểu rằng câu trả lời của James là từ năm 2008 :)
WTFZane

26

bạn phải làm:

LIKE '%' + @param + '%'


giải pháp tuyệt vời - sẽ cung cấp cho nó nhiều hơn +1 nếu có thể! Cảm ơn
BM

2

Bạn có thể phải nối các dấu% với tham số của mình, ví dụ:

THÍCH '%' || @query || '%'

Chỉnh sửa: Thực ra, điều đó có thể không có ý nghĩa gì cả. Tôi nghĩ rằng tôi có thể đã hiểu sai vấn đề của bạn.


1

Đôi khi ký hiệu được sử dụng làm trình giữ chỗ %không giống nhau nếu bạn thực hiện một truy vấn từ VB như khi bạn thực thi nó từ MS SQL / Access. Hãy thử thay đổi biểu tượng giữ chỗ của bạn từ %thành *. Điều đó có thể hoạt động.
Tuy nhiên, nếu bạn gỡ lỗi và muốn sao chép trực tiếp chuỗi SQL của mình trong MS SQL hoặc Access để kiểm tra nó, bạn có thể phải thay đổi ký hiệu trở lại %trong MS SQL hoặc Access để thực sự trả về giá trị.

Hi vọng điêu nay co ich


Tôi không biết chắc vào năm 2012, nhưng% vs * này dành riêng cho các động cơ ADO và DAO. Nếu bạn đang sử dụng DAO, hoặc Current () trong Access, ký tự đại diện là *; nếu sử dụng ADO từ bất kỳ mã nào, bao gồm VBA bên trong Access, Ký tự đại diện là%.
Marcelo Scofano

0

cũng thử theo cách này

Dim cmd as New SqlCommand("SELECT * FROM compliance_corner WHERE (body LIKE CONCAT('%',@query,'%')  OR  title LIKE CONCAT('%',@query,'%') )")
cmd.Parameters.Add("@query", searchString)
cmd.ExecuteNonQuery()

Concat đã sử dụng thay vì +

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.