尝试插入视图时,无法修改映射到非密钥保留表错误的列

And*_*oid 6 sql oracle join

我有t1桌子no number(3)name varchar2(20)

emp其表empno,ename,job等列.

现在我创造了一个观点

create view v_t as select * from t1,emp;
Run Code Online (Sandbox Code Playgroud)

它创造了视图.然后我试图在v_t视图中插入值,但它给了我错误

无法修改映射到非密钥保留表的列

这是一个链接

我究竟做错了什么?

Aar*_*ron 5

假设t1表和emp表都有主键,视图可以识别为唯一,我猜测问题在于你如何指定你的JOIN.你现在所拥有的东西看起来会创建一个笛卡尔积(从一个表中的每一行不加选择地加入到另一个的每一行),这可能不会满足密钥保留表的要求(在问题中引用)你链接上面).

您在FROM子句中指定了隐式JOIN,但我没有看到任何JOIN条件(读取:WHERE子句).通过查看您的模式,我将假设您可以像这样在t1.no = emp.empno上加入:

create view v_t as 
select * 
from t1,emp
where t1.no = emp.empno;
Run Code Online (Sandbox Code Playgroud)

或者使用显式JOIN:

create view v_t as
select *
from t1
inner join emp on emp.empno = t1.no;
Run Code Online (Sandbox Code Playgroud)

Oracle将允许对具有相同类型和名称的列的表进行NATURAL JOIN(不指定JOIN条件).当然,因为没有和empno有不同的名字,这是行不通的.

现在您的CREATE VIEW已经平方,让我们进入INSERT.只要表是密钥保留的,您就可以基于JOIN插入到VIEW中,并且不会尝试一次INSERT到多个基表.在您的情况下,这意味着编写两个单独的INSERT语句或编写INSTEAD OF触发器:

CREATE TRIGGER v_t_insteadof
INSTEAD OF INSERT ON v_t

FOR EACH ROW
BEGIN 

INSERT INTO t1 (no, name)
VALUES(:new.no, :new.name); 

INSERT INTO emp (empno, ename, job)
VALUES(:new.no, :new.ename, :new.job); 

END v_t_insteadof;
Run Code Online (Sandbox Code Playgroud)

请注意,您需要根据该表中可能存在的其他字段调整INSERT INTO\temp.此外,您的INSERT命令将需要专门命名字段:

INSERT INTO v_t (no, name, ename, job) VALUES (59, 'Bob', 'Bobs Ename', 'Bobs Job');
Run Code Online (Sandbox Code Playgroud)