Tiền tố sql
mở ra một StringContext
nơi bạn có thể thiết lập các thông số SQL. Không có tham số SQL cho một danh sách, vì vậy bạn có thể dễ dàng kết thúc việc tự mở SQL injection ở đây nếu bạn không cẩn thận. Có một số gợi ý tốt (và một số nguy hiểm) về xử lý vấn đề này với SQLServer trên this question. Bạn có một vài lựa chọn:
Tốt nhất có lẽ là sử dụng các nhà điều hành #$
cùng với mkString
để suy SQL động:
val sql = sql"""SELECT * FROM coffee WHERE id IN (#${ids.mkString(",")})"""
này không sử dụng đúng các thông số và do đó có thể mở cửa cho SQL- tiêm và các vấn đề khác.
Một lựa chọn khác là sử dụng chuỗi suy thường xuyên và mkString
để xây dựng báo cáo kết quả:
val query = s"""SELECT * FROM coffee WHERE id IN (${ids.mkString(",")})"""
StaticQuery.queryNA[Coffee](query)
Đây thực chất là phương pháp tương tự như sử dụng #$
, nhưng có thể linh hoạt hơn trong trường hợp tổng quát.
Nếu lỗ hổng SQL injection là mối quan tâm chính (ví dụ: nếu các thành phần của ids
là người dùng được cung cấp), bạn có thể tạo truy vấn có tham số cho từng phần tử ids
. Sau đó, bạn sẽ cần phải cung cấp một ví dụ tùy chỉnh SetParameter
để trơn có thể biến List
vào các thông số:
implicit val setStringListParameter = new SetParameter[List[String]]{
def apply(v1: List[String], v2: PositionedParameters): Unit = {
v1.foreach(v2.setString)
}
}
val idsInClause = List.fill(ids.length)("?").mkString("(", ",", ")")
val query = s"""SELECT * FROM coffee WHERE id IN ($idsInClause)"""
Q.query[List[String], String](query).apply(ids).list(s)
Kể từ khi bạn ids
là Ints
, điều này có lẽ ít hơn của một mối quan tâm, nhưng nếu bạn thích phương pháp này, bạn sẽ chỉ cần phải thay đổi setStringListParameter
sử dụng Int
thay vì String
:
Nếu 'id' có loại' Danh sách [Int] 'Tôi không thể xem cách tiêm sql là có thể ngay cả khi họ được người dùng cung cấp. – Daenyth
@Daenyth Nó chắc chắn ít quan tâm (mặc dù đôi khi số nguyên SQL injection có thể là một vấn đề, do nguyên nhân chia cho số không hoặc ngoại lệ khác, và sau đó khai thác trạng thái không thành công - Google "sql injection integer"). Nhưng tôi muốn nói cách tốt nhất là sử dụng thông số để tránh các sự cố trên đường (ví dụ: nếu nhà phát triển khác thay đổi loại thành 'Chuỗi' xuống để chứa các loại ID mới bao gồm một số ký tự). Tôi đã thực sự chỉ bao gồm các trường hợp khi nó là một 'String' ở đây. –
Cảm ơn câu trả lời Ben! Rất thông tin về các giải pháp có lỗ hổng có thể xảy ra. Tuy nhiên, tôi đồng ý với @Daenyth rằng bạn không thể sql tiêm với một loại số nguyên rõ ràng. –