Scritto da Giuseppe Broccolo
A partire da PostgreSQL 9.3, è possibile aggiornare e inserire direttamente nelle viste, purché la vista faccia riferimento a una sola tabella sottostante.
PostgreSQL 9.4 ci consente di utilizzare la clausola CHECK per INSERT in viste aggiornabili. Si consideri ad esempio una tabella composta da una sola colonna intera; e consideriamo due viste, una sui numeri divisibili per 2 e una sui numeri divisibili per 3. Se proviamo a inserire il numero 123 nella prima vista:
—-
$ CREATE TABLE some_data(id int4 CHIAVE PRIMARIA);
CREA TABELLA
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id%2;
CREA VISUALIZZA
$ CREATE VIEW secondo AS SELECT * FROM some_data WHERE 0 =id%3;
CREA VISUALIZZA
$ INSERT IN first(id) VALUES (123);
—-
Verrà inserito nella tabella sottostante, anche se la vista è solo per numeri divisibili per 2 (quindi il nuovo valore non sarà visibile nella vista). In PostgreSQL 9.4 è stata introdotta la clausola CHECK per gestire correttamente gli INSERT nelle viste controllando preventivamente che i valori siano compatibili con la definizione della vista.
Ci sono due opzioni possibili:
* VERIFICA A CASCATA:questa è l'opzione predefinita, in cui i controlli si sovrappongono ad altre viste definite sulla stessa tabella sottostante
* CONTROLLO LOCALE – viene controllata solo la vista che è la destinazione di un INSERT
Qui viene mostrato come utilizzare la clausola CHECK nell'esempio precedente:
—-
$ DROP VIEW prima;
VISTA A CADUTA
$ DROP VIEW secondo;
VISTA A CADUTA
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2 WITH CHECK OPTION;
CREA VISUALIZZA
$ CREATE VIEW second AS SELECT * FROM some_data WHERE 0 =id % 3 WITH CHECK OPTION;
CREA VISUALIZZA
$ CREATE VIEW terzo AS SELECT * FROM first WHERE 0 =id % 3 WITH CHECK OPTION;
CREA VISUALIZZA
$ INSERT IN first(id) VALUES (14);
INSERIRE 0 1
$ INSERT IN first(id) VALUES (15);
ERRORE: la nuova riga viola WITH CHECK OPTION per la visualizzazione "prima"
$ INSERT IN VALUES second(id) (15);
INSERIRE 0 1
$ INSERT IN Third(id) VALUES (6);
INSERIRE 0 1
$ INSERT IN Third(id) VALUES (15);
ERRORE: la nuova riga viola WITH CHECK OPTION per la visualizzazione "prima"
Si noti che la vista "terza" è definita sulla vista "prima".
Il valore '14' è inserito correttamente nella prima vista, mentre il valore '15' può essere inserito solo nella seconda, non nella prima, come previsto. Possiamo inserire '6' nella terza vista perché è divisibile sia per 3 che per 2. L'errore sull'inserimento di '15' nella terza vista anche se è divisibile per 3 è perché viola la clausola CHECK divisibile per 2 prima nella vista genitore. In questo caso, non è sufficiente utilizzare una clausola LOCAL CHECK in entrambe le viste per aggirare il problema:
—-
$ DROP VIEW prima;
VISTA A CADUTA
$ DROP VIEW terzo;
VISTA A CADUTA
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2 CON OPZIONE DI CONTROLLO LOCALE;
CREA VISUALIZZA
$ CREATE VIEW terzo AS SELECT * FROM first WHERE 0 =id % 3 CON OPZIONE DI CONTROLLO LOCALE;
CREA VISUALIZZA
$ INSERT IN Third(id) VALUES (15);
ERRORE: la nuova riga viola WITH CHECK OPTION per la visualizzazione "prima"
—-
L'esempio di lavoro è mostrato qui:
—-
$ DROP VIEW prima;
VISTA A CADUTA
$ DROP VIEW terzo;
VISTA A CADUTA
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2;
CREA VISUALIZZA
$ CREATE VIEW terzo AS SELECT * FROM first WHERE 0 =id % 3 CON OPZIONE DI CONTROLLO LOCALE;
CREA VISUALIZZA
$ INSERT IN Third(id) VALUES (15);
INSERIRE 0 1
—-
Conclusioni
Questo nuovo meccanismo di verifica può essere applicato direttamente sulle viste aggiornabili durante la fase di INSERT. Rafforza sempre di più il ruolo del database nel mantenimento dell'integrità dei dati.