Napisane przez Giuseppe Broccolo
Od wersji PostgreSQL 9.3 możliwa jest aktualizacja i bezpośrednie wstawianie do widoków, o ile widok odnosi się tylko do jednej tabeli bazowej.
PostgreSQL 9.4 pozwala nam na użycie klauzuli CHECK dla INSERT w widokach, które można aktualizować. Rozważmy na przykład tabelę składającą się tylko z jednej kolumny liczb całkowitych; i rozważmy dwa widoki, jeden na liczbach podzielnych przez 2 i jeden na liczbach podzielnych przez 3. Jeśli spróbujemy wstawić liczbę 123 do pierwszego widoku:
—-
$ CREATE TABLE some_data(id int4 PRIMARY KEY);
UTWÓRZ TABELĘ
$ CREATE VIEW najpierw AS SELECT * FROM some_data WHERE 0 =id%2;
UTWÓRZ WIDOK
$ CREATE VIEW drugi AS SELECT * FROM some_data WHERE 0 =id%3;
UTWÓRZ WIDOK
$ WSTAW W pierwsze (id) WARTOŚCI (123);
—-
Zostanie on wstawiony do tabeli bazowej, mimo że widok dotyczy tylko liczb podzielnych przez 2 (więc nowa wartość nie będzie widoczna w widoku). W PostgreSQL 9.4 wprowadzono klauzulę CHECK, aby prawidłowo zarządzać INSERTami w widokach poprzez wcześniejsze sprawdzenie, czy wartości są zgodne z definicją widoku.
Istnieją dwie możliwe opcje:
* KONTROLA KASKADOWA – jest to opcja domyślna, w której sprawdza się kaskadowo do innych widoków zdefiniowanych w tej samej tabeli bazowej
* KONTROLA LOKALNA – sprawdzany jest tylko widok będący celem INSERT
Tutaj pokazano, jak używać klauzuli CHECK w powyższym przykładzie:
—-
$ Najpierw DROP VIEW;
UPUŚĆ WIDOK
$ DROP VIEW drugi;
UPUŚĆ WIDOK
$ CREATE VIEW najpierw AS SELECT * FROM some_data WHERE 0 =id % 2 Z opcją CHECK;
UTWÓRZ WIDOK
$ CREATE VIEW drugi AS SELECT * FROM some_data GDZIE 0 =id % 3 Z opcją CHECK;
UTWÓRZ WIDOK
$ CREATE VIEW trzeci AS SELECT * FROM first WHERE 0 =id % 3 Z opcją CHECK;
UTWÓRZ WIDOK
$ WSTAW W pierwsze (id) WARTOŚCI (14);
WSTAW 0 1
$ WSTAW W pierwsze (id) WARTOŚCI (15);
BŁĄD:nowy wiersz narusza Z OPCJĄ SPRAWDZANIA dla widoku „pierwszy”
$ WSTAW W drugie (id) WARTOŚCI (15);
WSTAW 0 1
$ WSTAW W Trzecie (id) WARTOŚCI (6);
WSTAW 0 1
$ WSTAW W trzecie (id) WARTOŚCI (15);
BŁĄD:nowy wiersz narusza Z OPCJĄ SPRAWDZANIA dla widoku „pierwszy”
Zwróć uwagę, że widok „trzeci” jest zdefiniowany w widoku „pierwszy”.
Wartość '14' jest wstawiona poprawnie w pierwszym widoku, natomiast wartość '15' może być wstawiona tylko w drugim, a nie pierwszym – jak oczekiwano. Możemy wstawić '6' do trzeciego widoku, ponieważ jest podzielna zarówno przez 3, jak i 2. Błąd przy wstawianiu '15' do trzeciego widoku, mimo że jest podzielna przez 3, wynika z tego, że narusza klauzulę 'divisible-by-2 CHECK' najpierw w widoku rodzica. W takim przypadku nie wystarczy użyć klauzuli LOCAL CHECK w obu widokach, aby obejść problem:
—-
$ Najpierw DROP VIEW;
UPUŚĆ WIDOK
$ DROP VIEW trzeci;
UPUŚĆ WIDOK
$ CREATE VIEW najpierw AS SELECT * FROM some_data GDZIE 0 =id % 2 Z LOKALNĄ OPCJĄ KONTROLI;
UTWÓRZ WIDOK
$ CREATE VIEW trzeci AS SELECT * FROM first GDZIE 0 =id % 3 Z LOKALNĄ KONTROLĄ;
UTWÓRZ WIDOK
$ WSTAW W trzecie (id) WARTOŚCI (15);
BŁĄD:nowy wiersz narusza Z OPCJĄ SPRAWDZANIA dla widoku „pierwszy”
—-
Przykład pracy pokazano tutaj:
—-
$ Najpierw DROP VIEW;
UPUŚĆ WIDOK
$ DROP VIEW trzeci;
UPUŚĆ WIDOK
$ CREATE VIEW najpierw AS SELECT * FROM some_data WHERE 0 =id % 2;
UTWÓRZ WIDOK
$ CREATE VIEW trzeci AS SELECT * FROM first GDZIE 0 =id % 3 Z LOKALNĄ KONTROLĄ;
UTWÓRZ WIDOK
$ WSTAW W trzecie (id) WARTOŚCI (15);
WSTAW 0 1
—-
Wnioski
Ten nowy mechanizm sprawdzania można zastosować bezpośrednio w widokach, które można aktualizować podczas fazy WSTAWIANIA. Coraz bardziej wzmacnia rolę bazy danych w utrzymaniu integralności danych.