TL; DR : Il faudrait restreindre tous les littéraux, pas seulement ceux des WHERE
clauses. Pour des raisons pour lesquelles ils ne le font pas, il permet à la base de données de rester découplée des autres systèmes.
Premièrement, votre prémisse est défectueuse. Vous souhaitez restreindre uniquement les WHERE
clauses, mais ce n'est pas le seul endroit où l'entrée utilisateur peut aller. Par exemple,
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
Ceci est également vulnérable à l'injection 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
Vous ne pouvez donc pas simplement restreindre les littéraux dans la WHERE
clause. Vous devez restreindre tous les littéraux.
Il nous reste maintenant la question: "Pourquoi autoriser les littéraux?" Gardez cela à l'esprit: bien que les bases de données relationnelles soient utilisées sous une application écrite dans une autre langue un pourcentage important du temps, il n'est pas nécessaire d' utiliser le code d'application pour utiliser la base de données. Et ici, nous avons une réponse: vous avez besoin de littéraux pour écrire du code. La seule autre alternative serait d'exiger que tout le code soit écrit dans une langue indépendante de la base de données. Les avoir vous donne donc la possibilité d'écrire du "code" (SQL) directement dans la base de données. Il s'agit d'un découplage précieux, et il serait impossible sans littéraux. (Essayez d'écrire dans votre langue préférée parfois sans littéraux. Je suis sûr que vous pouvez imaginer à quel point cela serait difficile.)
À titre d'exemple courant, les littéraux sont souvent utilisés dans la population des tables de liste de valeurs / de recherche:
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');
Sans eux, vous auriez besoin d'écrire du code dans un autre langage de programmation juste pour remplir ce tableau. La possibilité de le faire directement en SQL est précieuse .
Il nous reste alors une autre question: pourquoi les bibliothèques clientes du langage de programmation ne le font-elles pas alors? Et ici, nous avons une réponse très simple: ils auraient ré-implémenté l'intégralité de l'analyseur de base de données pour chaque version prise en charge de la base de données . Pourquoi? Parce qu'il n'y a pas d'autre moyen de garantir que vous avez trouvé chaque littéral. Les expressions régulières ne suffisent pas. Par exemple: cela contient 4 littéraux distincts dans 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$$;
Essayer de le faire serait un cauchemar de maintenance, d'autant plus que la syntaxe valide change souvent entre les principales versions des bases de données.
bad_ideas_sql = 'SELECT title FROM idea WHERE idea.status == "bad" AND idea.user == :mwheeler'
aurait à la fois des valeurs codées en dur et paramétrées dans une seule requête - essayez d'attraper cela! Je pense qu'il existe des cas d'utilisation valables pour de telles requêtes mixtes.