我在 Oracle 11g 数据库中创建了一个视图,该数据库由两个连接表组成,如下所示:
CREATE FORCE VIEW my_dataview
(
key1,
key2,
column_from_table1,
column_from_table2
)
AS
SELECT key1,
key2,
column_from_table1,
column_from_table2
FROM table1
NATURAL LEFT OUTER JOIN table2;
其中两个源表都有两个名为key1
and的主键key2
。数据正在正确聚合,但我无法table2
直接从视图更新任何列。
如果我要执行以下更新,
UPDATE my_dataview SET column_from_table2 = 'Hello, world'
WHERE key1 = 1234
AND key2 = 12;
它给出的错误是ORA-01779 cannot modify a column which maps to a non key-preserved table
。这也凸显了column_from_table2
. 如果我要执行相同的命令,但column_from_table1
改为设置,它可以工作。我认为这可能是因为 table1 是连接中所需的表。
我首先想到的可能是因为我加入了主键,并且视图中只有一个结果列,这可以解释我的问题。但是即使在视图中添加单独的列table2.key1
和table2.key2
列也没有改变任何东西,除了不必要地复制数据。
我知道可以使用 INSTEAD OF 触发器来更新视图,但我更愿意尽可能保持清洁——这似乎更像是一种 hack,而不是一种解决方案。
所以总结一下我的问题,在连接视图上启用插入、更新和删除的最佳行动计划是什么,以至于根本无法判断它是由两个单独的表组成的视图?
根据要求的表定义:
CREATE TABLE table1
(
key1 NUMBER(5) NOT NULL,
key2 NUMBER(2) NOT NULL,
column_from_table_1 DATE
);
CREATE UNIQUE INDEX pk_table1_index ON table1
(key1, key2);
ALTER TABLE table1 ADD (
CONSTRAINT table1_Pkey
PRIMARY KEY
(key1, key2)
USING INDEX pk_table1_index
ENABLE VALIDATE);
CREATE TABLE table2
(
key1 NUMBER(5) NOT NULL,
key2 NUMBER(2) NOT NULL,
column_from_table_2 VARCHAR2(20)
);
CREATE UNIQUE INDEX pk_table2_index ON table2
(key1, key2);
ALTER TABLE table2 ADD (
CONSTRAINT table2_Pkey
PRIMARY KEY
(key1, key2)
USING INDEX pk_table2_index
ENABLE VALIDATE);