Geschreven door Giuseppe Broccolo
Sinds PostgreSQL 9.3 is het mogelijk om views rechtstreeks bij te werken en in te voegen, zolang de view maar naar één onderliggende tabel verwijst.
Met PostgreSQL 9.4 kunnen we de CHECK-component voor INSERT's gebruiken in bijwerkbare views. Beschouw bijvoorbeeld een tabel die uit slechts één geheeltallige kolom bestaat; en overweeg twee weergaven, één op getallen die deelbaar zijn door 2 en één op getallen die deelbaar zijn door 3. Als we proberen het getal 123 in de eerste weergave in te voegen:
—-
$ MAAK TABEL some_data(id int4 PRIMAIRE SLEUTEL);
MAAK TAFEL
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id%2;
AANBEELDING MAKEN
$ CREATE VIEW second AS SELECT * FROM some_data WHERE 0 =id%3;
AANBEELDING MAKEN
$ INSERT INTO first(id) VALUES (123);
—-
Het wordt ingevoegd in de onderliggende tabel, ook al is de weergave alleen voor getallen die deelbaar zijn door 2 (de nieuwe waarde is dus niet zichtbaar in de weergave). In PostgreSQL 9.4 is de CHECK-component geïntroduceerd om INSERT's in views correct te beheren door vooraf te controleren of de waarden compatibel zijn met de definitie van de view.
Er zijn twee mogelijke opties:
* CASCADED CONTROLE – dit is de standaardoptie, waarbij cheques trapsgewijs naar andere weergaven die zijn gedefinieerd op dezelfde onderliggende tabel
* LOKALE CONTROLE – alleen de weergave die het doel is van een INSERT wordt gecontroleerd
Hier wordt getoond hoe u de CHECK-component in het bovenstaande voorbeeld gebruikt:
—-
$ DROP VIEW eerst;
DROP VIEW
$ DROP VIEW tweede;
DROP VIEW
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2 MET CHECK OPTION;
AANBEELDING MAKEN
$ CREATE VIEW second AS SELECT * FROM some_data WHERE 0 =id % 3 MET CHECK OPTION;
AANBEELDING MAKEN
$ CREATE VIEW derde ALS SELECT * VANAF eerste WAAR 0 =id % 3 MET CONTROLE OPTIE;
AANBEELDING MAKEN
$ INSERT INTO first(id) VALUES (14);
INSERT 0 1
$ INSERT INTO first(id) VALUES (15);
FOUT:nieuwe rij schendt MET CONTROLEER OPTIE voor weergave "eerste"
$ INSERT INTO second(id) VALUES (15);
INSERT 0 1
$ INSERT INTO third(id) VALUES (6);
INSERT 0 1
$ INSERT INTO third(id) VALUES (15);
FOUT:nieuwe rij schendt MET CONTROLEER OPTIE voor weergave "eerste"
Merk op dat de weergave "derde" is gedefinieerd op de weergave "eerste".
De waarde '14' is correct ingevoegd in de eerste weergave, terwijl de waarde '15' alleen in de tweede kan worden ingevoegd, niet in de eerste - zoals verwacht. We kunnen '6' invoegen in de derde weergave omdat deze deelbaar is door zowel 3 als 2. De fout over het invoegen van '15' in de derde weergave, ook al is het deelbaar door 3, is omdat het de deelbaar-door-2-CHEQUE-clausule schendt eerst in de bovenliggende weergave. In dit geval is het niet voldoende om in beide weergaven een LOCAL CHECK-component te gebruiken om het probleem te omzeilen:
—-
$ DROP VIEW eerst;
DROP VIEW
$ DROP VIEW derde;
DROP VIEW
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2 MET LOKALE CONTROLE OPTIE;
AANBEELDING MAKEN
$ CREATE VIEW derde ALS SELECT * VANAF eerste WAAR 0 =id % 3 MET LOKALE CONTROLE OPTIE;
AANBEELDING MAKEN
$ INSERT INTO third(id) VALUES (15);
FOUT:nieuwe rij schendt MET CONTROLEER OPTIE voor weergave "eerste"
—-
Het werkvoorbeeld wordt hier getoond:
—-
$ DROP VIEW eerst;
DROP VIEW
$ DROP VIEW derde;
DROP VIEW
$ CREATE VIEW first AS SELECT * FROM some_data WHERE 0 =id % 2;
AANBEELDING MAKEN
$ CREATE VIEW derde ALS SELECT * VANAF eerste WAAR 0 =id % 3 MET LOKALE CONTROLE OPTIE;
AANBEELDING MAKEN
$ INSERT INTO third(id) VALUES (15);
INSERT 0 1
—-
Conclusies
Dit nieuwe controlemechanisme kan tijdens de INSERT-fase direct worden toegepast op bij te werken views. Het versterkt steeds meer de rol van de database bij het handhaven van de gegevensintegriteit.