Oracle - 更新联接 - 非键保留表
我正在尝试复制 Ingres“从 tbl2 更新 tbl1”命令,该命令在 Oracle 中并不存在。
所以我使用“update (select tbl1 join tbl2...)”命令。两个表都定义了主键,我认为我的联接唯一标识行,但我仍然收到“ORA-01779:无法修改映射到非键保留表的列”。
以下是适当的匿名表定义和我尝试执行的更新:
CREATE TABLE tbl1
(
ID decimal(11) NOT NULL,
A varchar2(3) NOT NULL,
B float(7),
CONSTRAINT tbl1_pk PRIMARY KEY (ID,A)
)
;
CREATE TABLE tbl2
(
ID decimal(11) NOT NULL,
A varchar2(3) NOT NULL,
B float(15),
C float(15),
D char(1) NOT NULL,
CONSTRAINT tbl2_PK PRIMARY KEY (ID,A,D)
)
;
UPDATE
(select tbl1.b, tbl2.c
from tbl1 inner join tbl2
on tbl1.id=tbl2.id
and tbl1.a=tbl2.a
and tbl1.b=tbl2.b
and tbl1.a='foo'
and tbl2.D='a')
set b=c;
如何定义我的选择,以便 Oracle 满意我没有唯一性违规?
I'm trying to replicate an Ingres "update tbl1 from tbl2" command, which doesn't exactly exist in Oracle.
So I use "update (select tbl1 join tbl2...)" command. Both tables have primary keys defined and I thought that my join was uniquely identifying rows, but I'm still getting "ORA-01779: cannot modify a column which maps to a non key-preserved table".
Here are suitably anonymized table definitions and the update I'm trying to execute:
CREATE TABLE tbl1
(
ID decimal(11) NOT NULL,
A varchar2(3) NOT NULL,
B float(7),
CONSTRAINT tbl1_pk PRIMARY KEY (ID,A)
)
;
CREATE TABLE tbl2
(
ID decimal(11) NOT NULL,
A varchar2(3) NOT NULL,
B float(15),
C float(15),
D char(1) NOT NULL,
CONSTRAINT tbl2_PK PRIMARY KEY (ID,A,D)
)
;
UPDATE
(select tbl1.b, tbl2.c
from tbl1 inner join tbl2
on tbl1.id=tbl2.id
and tbl1.a=tbl2.a
and tbl1.b=tbl2.b
and tbl1.a='foo'
and tbl2.D='a')
set b=c;
How can I define my select such that Oracle will be satisfied that I have no uniqueness violations?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该能够使用相关子查询来完成此操作。
您所编写的
UPDATE
的问题是 Oracle 无法保证恰好有 1 个tbl2.c
值对应于单个tbl1.b
值。如果tbl1
中的任何特定行在tbl2
中存在多行,则相关更新将引发错误,指示单行子查询返回多行。在这种情况下,您需要向子查询添加一些逻辑,以指定在这种情况下使用 tbl2 中的哪一行。You should be able to do this with a correlated subquery
The problem with the
UPDATE
that you've written is that Oracle cannot guarantee that there is exactly 1tbl2.c
value that corresponds to a singletbl1.b
value. If there are multiple rows intbl2
for any particular row intbl1
, the correlated update is going to throw an error indicating that a single-row subquery returned multiple rows. In that case, you'd need to add some logic to the subquery to specify which row fromtbl2
to use in that case.此语句失败并出现错误(ORA-01779 无法修改映射到非键保留表的列),因为它尝试修改基本 tbl1 表,而 tbl1 表在视图中未进行键保留。
因为虽然(ID,A)是dept表的键,但它不是连接的键。
This statement fails with an error (ORA-01779 cannot modify a column which maps to a non key-preserved table), because it attempts to modify the base tbl1table, and the tbl1 table is not key-preserved in the view .
because although (ID,A) is a key of the dept table, it is not a key of the join.
根据 (http://www.orafaq .com/tuningguide/updateable%20view.html)。事实上,您的加入不是主键,这似乎是不允许的。
It seems your view is not a key-preserved view according to (http://www.orafaq.com/tuningguide/updateable%20view.html). Indeed you make your join on not primary key which seems to be not allowed.