TL; DR : Você precisaria restringir todos os literais, não apenas osWHERE
cláusulas. Por razões que não o fazem, ele permite que o banco de dados permaneça dissociado de outros sistemas.
Em primeiro lugar, sua premissa é falha. Você deseja restringir apenas WHERE
cláusulas, mas esse não é o único local para entrada do usuário. Por exemplo,
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
Isso é igualmente vulnerável à injeção de 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
Portanto, você não pode restringir literais na WHERE
cláusula. Você tem que restringir tudo literais.
Agora ficamos com a pergunta: "Por que permitir literais?" Lembre-se disso: embora os bancos de dados relacionais sejam usados sob um aplicativo gravado em outro idioma em uma grande porcentagem do tempo, não é necessário que você use o código do aplicativo para usar o banco de dados. E aqui temos uma resposta: você precisa de literais para escrever código. A única outra alternativa seria exigir que todo o código fosse escrito em algum idioma independente do banco de dados. Portanto, tê-los oferece a capacidade de escrever "código" (SQL) diretamente no banco de dados. Este é um desacoplamento valioso e seria impossível sem literais. (Tente escrever em seu idioma favorito em algum momento sem literais. Tenho certeza de que você pode imaginar o quão difícil isso seria.)
Como um exemplo comum, os literais são frequentemente usados na população de tabelas de lista de valores / consulta:
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');
Sem eles, você precisaria escrever código em outra linguagem de programação apenas para preencher esta tabela. A capacidade de fazer isso diretamente no SQL é valiosa .
Ficamos então com mais uma pergunta: por que as bibliotecas cliente de linguagem de programação não o fazem? E aqui temos uma resposta muito simples: eles teriam que reimplementar o analisador de banco de dados inteiro para cada versão suportada do banco de dados . Por quê? Porque não há outra maneira de garantir que você encontrou todos os literais. Expressões regulares não são suficientes. Por exemplo: este contém 4 literais separados no 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$$;
Tentar fazer isso seria um pesadelo de manutenção, especialmente porque a sintaxe válida geralmente muda entre as principais versões dos bancos de dados.
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
teria valores codificados e parametrizados em uma única consulta - tente entender isso! Eu acho que existem casos de uso válidos para essas consultas mistas.