TL; DR : Bạn sẽ phải hạn chế tất cả các nghĩa đen, không chỉ những từ trong WHERE
mệnh đề. Vì lý do tại sao họ không, nó cho phép cơ sở dữ liệu vẫn tách rời khỏi các hệ thống khác.
Thứ nhất, tiền đề của bạn là thiếu sót. Bạn muốn hạn chế chỉ WHERE
các mệnh đề, nhưng đó không phải là nơi duy nhất người dùng nhập liệu có thể đi. Ví dụ,
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
Điều này cũng dễ bị tổn thương khi tiêm SQL:
SELECT
COUNT(CASE WHEN item_type = 'blender' THEN 1 END) FROM item; DROP TABLE user_info; SELECT CASE(WHEN item_type = 'blender' THEN 1 END) as type1_count,
COUNT(CASE WHEN item_type = 'television' THEN 1 END) AS type2_count)
FROM item
Vì vậy, bạn không thể chỉ giới hạn nghĩa đen trong WHERE
mệnh đề. Bạn phải hạn chế tất cả các chữ.
Bây giờ chúng tôi còn lại với câu hỏi, "Tại sao lại cho phép chữ?" Hãy ghi nhớ điều này: trong khi cơ sở dữ liệu quan hệ được sử dụng bên dưới một ứng dụng được viết bằng ngôn ngữ khác với tỷ lệ lớn thời gian, không có yêu cầu nào bạn phải sử dụng mã ứng dụng để sử dụng cơ sở dữ liệu. Và ở đây chúng tôi có một câu trả lời: bạn cần chữ để viết mã. Sự thay thế duy nhất khác là yêu cầu tất cả các mã được viết bằng một số ngôn ngữ độc lập với cơ sở dữ liệu. Vì vậy, có chúng cung cấp cho bạn khả năng viết "mã" (SQL) trực tiếp trong cơ sở dữ liệu. Đây là một sự tách rời có giá trị, và nó sẽ là không thể nếu không có chữ. (Hãy thử viết bằng ngôn ngữ yêu thích của bạn đôi khi không có chữ. Tôi chắc chắn bạn có thể tưởng tượng điều này sẽ khó khăn như thế nào.)
Như một ví dụ phổ biến, nghĩa đen thường được sử dụng trong quần thể bảng liệt kê giá trị / tra cứu:
CREATE TABLE user_roles (role_id INTEGER, role_name VARCHAR(50));
INSERT INTO user_roles (1, 'normal');
INSERT INTO user_roles (2, 'admin');
INSERT INTO user_roles (3, 'banned');
Nếu không có chúng, bạn sẽ cần phải viết mã bằng ngôn ngữ lập trình khác chỉ để điền vào bảng này. Khả năng làm như vậy trực tiếp trong SQL là có giá trị .
Sau đó, chúng tôi lại có thêm một câu hỏi: tại sao các thư viện khách ngôn ngữ lập trình lại không làm điều đó? Và ở đây chúng tôi có một câu trả lời rất đơn giản: họ sẽ thực hiện lại toàn bộ trình phân tích cơ sở dữ liệu cho từng phiên bản cơ sở dữ liệu được hỗ trợ . Tại sao? Bởi vì không có cách nào khác để đảm bảo bạn đã tìm thấy mọi nghĩa đen. Biểu thức thông thường không đủ. Ví dụ: phần này chứa 4 chữ riêng biệt trong PostgreSQL:
SELECT $lit1$I'm a literal$lit1$||$lit2$I'm another literal $$ with nested string delimiters$$ $lit2$||'I''m ANOTHER literal'||$$I'm the last literal$$;
Cố gắng làm điều đó sẽ là một cơn ác mộng bảo trì, đặc biệt là vì cú pháp hợp lệ thường thay đổi giữa các bản phát hành cơ sở dữ liệu chính.
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
sẽ có cả giá trị được mã hóa cứng và tham số hóa trong một truy vấn duy nhất - hãy thử nắm bắt điều đó! Tôi nghĩ rằng có những trường hợp sử dụng hợp lệ cho các truy vấn hỗn hợp như vậy.