TL; DR : Tendría que restringir todos los literales, no solo los de las WHERE
cláusulas. Por razones que no lo hacen, permite que la base de datos permanezca desacoplada de otros sistemas.
En primer lugar, su premisa es defectuosa. Desea restringir solo las WHERE
cláusulas, pero ese no es el único lugar al que puede ir la entrada del usuario. Por ejemplo,
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
Esto es igualmente vulnerable a la inyección 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
Por lo tanto, no puede limitar los literales en la WHERE
cláusula. Tienes que restringir todos los literales.
Ahora nos queda la pregunta: "¿Por qué permitir literales?" Tenga esto en cuenta: si bien las bases de datos relacionales se usan debajo de una aplicación escrita en otro idioma la mayor parte del tiempo, no es necesario que use el código de la aplicación para usar la base de datos. Y aquí tenemos una respuesta: necesitas literales para escribir código. La única otra alternativa sería requerir que todo el código se escriba en un idioma independiente de la base de datos. Así que tenerlos le da la capacidad de escribir "código" (SQL) directamente en la base de datos. Este es un desacoplamiento valioso, y sería imposible sin literales. (Intente escribir en su idioma favorito en algún momento sin literales. Estoy seguro de que puede imaginar lo difícil que sería).
Como ejemplo común, los literales a menudo se usan en la población de tablas de lista de valores / búsqueda:
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');
Sin ellos, necesitaría escribir código en otro lenguaje de programación solo para completar esta tabla. La capacidad de hacerlo directamente en SQL es valiosa .
Luego nos queda una pregunta más: ¿por qué no lo hacen las bibliotecas cliente de lenguaje de programación? Y aquí tenemos una respuesta muy simple: habrían vuelto a implementar todo el analizador de la base de datos para cada versión compatible de la base de datos . ¿Por qué? Porque no hay otra manera de garantizar que hayas encontrado todos los literales. Las expresiones regulares no son suficientes. Por ejemplo: esto contiene 4 literales separados en 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$$;
Intentar hacerlo sería una pesadilla de mantenimiento, especialmente porque la sintaxis válida a menudo cambia entre las principales versiones de las bases de datos.
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
tendría valores codificados y parametrizados en una sola consulta. ¡Intente captar eso! Creo que hay casos de uso válidos para tales consultas mixtas.