Skrevet af Giuseppe Broccolo
Siden PostgreSQL 9.3 er det muligt at opdatere og indsætte i visninger direkte, så længe visningen kun refererer til én underliggende tabel.
PostgreSQL 9.4 giver os mulighed for at bruge CHECK-klausulen til INSERT'er i opdaterbare visninger. Overvej f.eks. en tabel, der kun består af én heltalskolonne; og overvej to visninger, et på tal, der er deleligt med 2 og et på tal, der er deleligt med 3. Hvis vi forsøger at indsætte tallet 123 i den første visning:
—-
$ CREATE TABLE some_data(id int4 PRIMÆR NØGLE);
OPRET TABEL
$ CREATE VIEW først SOM SELECT * FROM some_data WHERE 0 =id%2;
OPRET VISNING
$ CREATE VIEW sekund SOM SELECT * FROM some_data WHERE 0 =id%3;
OPRET VISNING
$ INSERT INTO first(id) VALUES (123);
—-
Det vil blive indsat i den underliggende tabel, selvom visningen kun er for tal, der er delelige med 2 (så den nye værdi vil ikke være synlig i visningen). I PostgreSQL 9.4 er CHECK-klausulen blevet introduceret for korrekt at administrere INSERTs i visninger ved på forhånd at kontrollere, at værdier er kompatible med definitionen af visningen.
Der er to mulige muligheder:
* CASCADED CHECK – dette er standardindstillingen, hvor checks kaskade til andre visninger defineret på den samme underliggende tabel
* LOKAL KONTROL – kun den visning, der er målet for en INSERT, kontrolleres
Her er vist, hvordan man bruger CHECK-sætningen i ovenstående eksempel:
—-
$ DROP VIEW først;
DROP VISNING
$ DROP VIEW sekund;
DROP VISNING
$ OPRET VISNING først SOM SELECT * FRA nogle_data WHERE 0 =id % 2 MED KONTROLMULIGHED;
OPRET VISNING
$ CREATE VIEW sekund SOM SELECT * FROM some_data WHERE 0 =id % 3 MED KONTROLMULIGHED;
OPRET VISNING
$ OPRET VISNING tredje SOM VÆLG * FRA først HVOR 0 =id % 3 MED KONTROLMULIGHED;
OPRET VISNING
$ INSERT INTO first(id) VALUES (14);
INDSÆT 0 1
$ INSERT INTO first(id) VALUES (15);
FEJL: ny række overtræder MED KONTROLMULIGHED for visningen "først"
$ INSERT INTO second(id) VALUES (15);
INDSÆT 0 1
$ INSERT INTO third(id) VALUES (6);
INDSÆT 0 1
$ INSERT INTO third(id) VALUES (15);
FEJL: ny række overtræder MED KONTROLMULIGHED for visningen "først"
Bemærk, at visningen "tredje" er defineret på visningen "først".
Værdien '14' er korrekt indsat i den første visning, mens værdien '15' kun kan indsættes i anden, ikke først - som forventet. Vi kan indsætte '6' i den tredje visning, fordi den er delelig med både 3 og 2. Fejlen ved at indsætte '15' i den tredje visning, selvom den er delelig med 3, skyldes, at den er i strid med delbar-med-2 CHECK-sætningen på forældresynet, først. I dette tilfælde er det ikke tilstrækkeligt at bruge en LOCAL CHECK-klausul i begge visninger for at løse problemet:
—-
$ DROP VIEW først;
DROP VISNING
$ DROP VIEW tredje;
DROP VISNING
$ OPRET VISNING først SOM SELECT * FRA nogle_data WHERE 0 =id % 2 MED LOKAL KONTROLMULIGHED;
OPRET VISNING
$ OPRET VISNING tredje SOM VÆLG * FRA først HVOR 0 =id % 3 MED LOKAL KONTROLMULIGHED;
OPRET VISNING
$ INSERT INTO third(id) VALUES (15);
FEJL: ny række overtræder MED KONTROLMULIGHED for visningen "først"
—-
Arbejdseksemplet er vist her:
—-
$ DROP VIEW først;
DROP VISNING
$ DROP VIEW tredje;
DROP VISNING
$ CREATE VIEW først SOM SELECT * FROM some_data WHERE 0 =id % 2;
OPRET VISNING
$ OPRET VISNING tredje SOM VÆLG * FRA først HVOR 0 =id % 3 MED LOKAL KONTROLMULIGHED;
OPRET VISNING
$ INSERT INTO third(id) VALUES (15);
INDSÆT 0 1
—-
Konklusioner
Denne nye kontrolmekanisme kan anvendes direkte på opdaterbare visninger under INSERT-fasen. Det forstærker mere og mere databasens rolle i at opretholde dataintegriteten.