Sql Oracle-更新联接-非键保留表

Sql Oracle-更新联接-非键保留表,sql,oracle,join,sql-update,Sql,Oracle,Join,Sql Update,我正在尝试从tbl2命令复制一个Ingres update tbl1,这在Oracle中并不存在 所以我使用更新选择tbl1加入tbl2。。。命令这两个表都定义了主键,我认为我的联接是唯一标识行的,但我仍然得到ORA-01779:无法修改映射到非键保留表的列 以下是适当匿名化的表定义和我尝试执行的更新: CREATE TABLE tbl1 ( ID decimal(11) NOT NULL, A varchar2(3) NOT NULL, B float(7), CONS

我正在尝试从tbl2命令复制一个Ingres update tbl1,这在Oracle中并不存在

所以我使用更新选择tbl1加入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;

如何定义我的select以使Oracle满意我没有违反唯一性的情况?

您应该能够使用相关的子查询来实现这一点

UPDATE tbl1 t1
   SET t1.b = (SELECT c
                 FROM tbl2 t2
                WHERE t1.id = t2.id
                  AND t1.a  = t2.a
                  AND t1.b  = t2.b
                  AND t2.d  = 'a')
 WHERE t1.a = 'foo'
   AND EXISTS( SELECT 1
                 FROM tbl2 t2
                WHERE t1.id = t2.id
                  AND t1.a  = t2.a
                  AND t1.b  = t2.b
                  AND t2.d  = 'a')

您编写的更新的问题是Oracle不能保证只有一个tbl2.c值对应于一个tbl1.b值。如果tbl1中的任何特定行在tbl2中有多行,则相关更新将抛出一个错误,指示单行子查询返回多行。在这种情况下,您需要向子查询添加一些逻辑,以指定在这种情况下使用tbl2中的哪一行。

此语句失败,出现错误ORA-01779无法修改映射到非键保留表的列,因为它试图修改基tbl1表,并且tbl1表在视图中没有键保留。
因为尽管ID,A是dept表的键,但它不是join的键。

根据,您的视图似乎不是键保留视图。确实,您在非主键上进行了加入,这似乎是不允许的。

这似乎解决了问题-感谢您的进一步解释。这是有道理的。这个链接已经不存在了,你能从正确的页面上更新或总结信息吗?它仍然存在,但现在已经存在了。它指的是:Oracle 11.2数据库管理员指南->§24管理视图、序列和同义词->§§关键保留表