4.3.3 Изменяемость представлений - Oracle
Расширения правил изменяемости представлений в Oracle следующие:
- допускаются вложенные запросы в фразе WHERE;
- допускается частичная возможность изменения представлений, определенных соединением таблиц.
Последнее свойство является наиболее интересным и оригинальным. Изменяемость соединенных представлений в Oracle базируется на концепции таблицы, охраняемой ключом. Таблица является охраняемой ключом, если ключ таблицы может также являться и ключом представления. В простейшем случае первичный или потенциальный ключ такой таблицы входит в представление. Операторы модификации воздействуют только на одну базовую таблицу в соединенном представлении - на таблицу, охраняемую ключом. Попытки изменить содержимое тех столбцов представления, которые отображают столбцы неохраняемой базовой таблицы, приведут к ошибкам.
Мы проиллюстрируем изменяемость представлений в Oracle на таблицах l и d, являющихся копиями таблиц department и location соответственно:
CREATE TABLE l(
l_id INTEGER PRIMARY KEY,
reg_gr VARCHAR(30)
);
CREATE TABLE d (
d_id INTEGER PRIMARY KEY,
name VARCHAR(30),
l_id INTEGER
);
INSERT INTO l SELECT * FROM location;
INSERT INTO d SELECT * FROM department;
CREATE VIEW dl (dn, name, ln, reg) AS
SELECT d_id, name, d.l_id, reg_gr
FROM d,l WHERE d.l_id=l.l_id;
Результат выборки SELECT * FROM dl будет:
DN NAME LN REG
-- -------------- --- ----------
10 ACCOUNTING 122 NEW YORK
20 RESEARCH 124 DALLAS
30 SALES 123 CHICAGO
40 OPERATIONS 167 BOSTON
12 RESEARCH 122 NEW YORK
13 SALES 122 NEW YORK
14 OPERATIONS 122 NEW YORK
23 SALES 124 DALLAS
24 OPERATIONS 124 DALLAS
34 OPERATIONS 123 CHICAGO
43 SALES 167 BOSTON
Далее мы приводим протокол выполнения некоторых операторов:
SQL> DELETE FROM dl WHERE dn=10;
1 row deleted.
SQL> UPDATE dl SET name='DEP1' WHERE dn=20;
1 row updated.
SQL> UPDATE dl SET name='DEP2' WHERE ln=124;
3 rows updated.
SQL> UPDATE dl SET reg='REG1' WHERE ln=123;
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table
SQL> UPDATE dl SET ln=168 WHERE ln=167;
2 rows updated.
SQL> INSERT INTO dl (dn,name,ln) VALUES (99,'NEW DEP',123);
1 row created.
SQL> INSERT INTO dl (dn,name,ln,reg) VALUES (98,'NEW DEP2',123,'BOSTON');
ERROR at line 1:
ORA-01776: cannot modify more than one base table through a join view
SQL>SELECT * FROM l;
L_ID REG_GR
---- --------
122 NEW YORK
124 DALLAS
123 CHICAGO
167 BOSTON
SQL> SELECT * FROM d;
D_ID NAME L_ID
---- ---------- ---------
20 DEP2 124
30 SALES 123
40 OPERATIONS 168
12 RESEARCH 122
13 SALES 122
14 OPERATIONS 122
23 DEP2 124
24 DEP2 124
34 OPERATIONS 123
43 SALES 168
99 NEW DEP 123
Как видите, все выполненные изменения относились только к базовой таблице d, так как именно ее ключ является и ключом представления dl.