TL; DR : dovresti limitare tutti letterali, non solo quelli in WHERE
clausole. Per ragioni che non lo fanno, consente al database di rimanere disaccoppiato da altri sistemi.
In primo luogo, la tua premessa è imperfetta. Vuoi limitare solo le clausole WHERE
, ma non è l'unico posto in cui l'input dell'utente può andare. Ad esempio,
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
Questo è ugualmente vulnerabile all'iniezione 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
Quindi non puoi semplicemente limitare i letterali nella clausola WHERE
. Devi limitare tutti letterali.
Ora ci rimane la domanda: "Perché consentire letteralmente i letterali?" Tenere presente questo: mentre i database relazionali vengono utilizzati sotto un'applicazione scritta in un'altra lingua per una grande percentuale del tempo, non esiste un requisito che sia necessario utilizzare il codice dell'applicazione per utilizzare il database. E qui abbiamo una risposta: hai bisogno di letterali per scrivere codice. L'unica altra alternativa sarebbe quella di richiedere che tutto il codice sia scritto in una lingua indipendente dal database. Quindi averli ti dà la possibilità di scrivere "codice" (SQL) direttamente nel database. Questo è un valido disaccoppiamento e sarebbe impossibile senza i letterali. (Prova a scrivere nella tua lingua preferita prima o poi letteralmente. Sono sicuro che puoi immaginare quanto sarebbe difficile.)
Come esempio comune, i letterali vengono spesso utilizzati nella popolazione delle tabelle list-of-value / look-up:
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');
Senza di essi, dovresti scrivere codice in un altro linguaggio di programmazione solo per popolare questa tabella. La possibilità di farlo direttamente in SQL è preziosa .
Ci rimane una domanda in più: perché non programmare le librerie client del linguaggio in quel momento? E qui abbiamo una risposta molto semplice: avrebbero re-implementare l'intero parser del database per ogni versione supportata del database. Perché? Perché non c'è altro modo per garantire di aver trovato ogni letterale. Le espressioni regolari non sono abbastanza. Ad esempio: questo contiene 4 letterali separati in 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$$;
Cercare di farlo sarebbe un incubo di manutenzione, soprattutto perché la sintassi valida spesso cambia tra le versioni principali dei database.