Написано от Джузепе Броколо
След PostgreSQL 9.3 е възможно да се актуализира и вмъква директно в изгледи, стига изгледът да се отнася само до една основна таблица.
PostgreSQL 9.4 ни позволява да използваме клаузата CHECK за INSERTs в обновяеми изгледи. Например, помислете за таблица, съставена само от една колона с цяло число; и разгледайте два изгледа, един за числа, делими на 2 и един за числа, делими на 3. Ако се опитаме да вмъкнем числото 123 в първия изглед:
---
$ CREATE TABLE some_data(id int4 ПРАВИЛЕН КЛЮЧ);
СЪЗДАВАНЕ НА ТАБЛИЦА
$ ПЪРВО СЪЗДАЙТЕ ИЗГЛЕД КАТО ИЗБОР * ОТ some_data КЪДЕ 0 =id%2;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ CREATE VIEW секунда КАТО SELECT * FROM some_data WHERE 0 =id%3;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ INSERT INTO first(id) STOS (123);
---
Той ще бъде вмъкнат в основната таблица, въпреки че изгледът е само за числа, делящи се на 2 (така че новата стойност няма да се вижда в изгледа). В PostgreSQL 9.4 клаузата CHECK е въведена за правилно управление на INSERT в изгледи, като се проверява предварително дали стойностите са съвместими с дефиницията на изгледа.
Има две възможни опции:
* КАСКАДНА ПРОВЕРКА – това е опцията по подразбиране, при която проверките преминават каскадно към други изгледи, дефинирани в същата основна таблица
* ЛОКАЛНА ПРОВЕРКА – проверява се само изгледът, който е целта на INSERT
Тук е показано как да използвате клаузата CHECK в горния пример:
---
$ ПУСКАНЕ ПРЕГЛЕД първо;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ DROP VIEW секунда;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ ПЪРВО СЪЗДАЙТЕ ИЗГЛЕД КАТО ИЗБЕРЕТЕ * ОТ some_data КЪДЕТО 0 =id % 2 С ОПЦИЯ ЗА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ CREATE VIEW секунда КАТО ИЗБОР * ОТ some_data КЪДЕТО 0 =id % 3 С ОПЦИЯ ЗА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ СЪЗДАЙТЕ ИЗГЛЕЖДАНЕ третото КАТО ИЗБЕРЕТЕ * ОТ първо, ОТКЪДЕ 0 =id % 3 С ОПЦИЯ ЗА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ INSERT INTO first(id) STOS (14);
INSE 0 1
$ INSERT INTO first(id) STOS (15);
ГРЕШКА: нов ред нарушава С ОПЦИЯ ЗА ПРОВЕРКА за изглед „първи“
$ INSERT INTO second(id) STOS (15);
INSE 0 1
$ INSERT INTO third(id) VALUES (6);
INSE 0 1
$ INSERT INTO third(id) VALUES (15);
ГРЕШКА: нов ред нарушава С ОПЦИЯ ЗА ПРОВЕРКА за изглед „първи“
Обърнете внимание, че изгледът „трети“ е дефиниран в изглед „първи“.
Стойността '14' е правилно вмъкната в първия изглед, докато стойността '15' може да се вмъкне само във втория, а не в първия - както се очаква. Можем да вмъкнем „6“ в третия изглед, защото се дели както на 3, така и на 2. Грешката при вмъкването на „15“ в третия изглед, въпреки че се дели на 3, е, защото нарушава клаузата за делимо на 2 CHECK първо в родителския изглед. В този случай не е достатъчно да използвате клауза LOCAL CHECK и в двата изгледа, за да заобиколите проблема:
---
$ ПУСКАНЕ ПРЕГЛЕД първо;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ DROP VIEW трети;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ ПЪРВО СЪЗДАЙТЕ ИЗГЛЕЖДАНЕ КАТО ИЗБОР * ОТ some_data КЪДЕТО 0 =id % 2 С ОПЦИЯ ЗА ЛОКАЛНА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ СЪЗДАЙТЕ ИЗГЛЕД трети КАТО ИЗБЕРЕТЕ * ОТ първо КЪДЕТО 0 =id % 3 С ОПЦИЯ ЗА ЛОКАЛНА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ INSERT INTO third(id) VALUES (15);
ГРЕШКА: нов ред нарушава С ОПЦИЯ ЗА ПРОВЕРКА за изглед „първи“
---
Работният пример е показан тук:
---
$ ПУСКАНЕ ПРЕГЛЕД първо;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ DROP VIEW трети;
ИЗПУСКАНЕ НА ИЗГЛЕД
$ ПЪРВО СЪЗДАЙТЕ ИЗГЛЕД КАТО ИЗБЕРЕТЕ * ОТ some_data WHERE 0 =id % 2;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ СЪЗДАЙТЕ ИЗГЛЕД трети КАТО ИЗБЕРЕТЕ * ОТ първо ОТКЪДЕ 0 =id % 3 С ОПЦИЯ ЗА ЛОКАЛНА ПРОВЕРКА;
СЪЗДАВАНЕ НА ИЗГЛЕД
$ INSERT INTO third(id) VALUES (15);
INSE 0 1
---
Заключения
Този нов механизъм за проверка може да се приложи директно към обновяеми изгледи по време на фазата INSERT. Той засилва все повече и повече ролята на базата данни за поддържане на целостта на данните.