我有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视图中插入值,但它给了我错误
无法修改映射到非密钥保留表的列
我究竟做错了什么?
假设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)
| 归档时间: |
|
| 查看次数: |
19402 次 |
| 最近记录: |