SQL> select * From v$version;
BANNER
----------------------------------------------------------------
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
PL/SQL Release 10.2.0.1.0 - Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 - Production
NLSRTL Version 10.2.0.1.0 - Production
SQL> select * From t1;
ID1 NAME
---------- ----------
1 AA
1 BB
1 CC
1 CC
2 B1
2 B2
4 B4
3 B4
4 BC
9 rows selected.
SQL> select * From t2;
ID1 NAME
---------- ----------
1 A1
2 B2
3 C3
4 D4
SQL> update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb;
update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table
SQL> create unique index ii on t2(id1);
SQL> update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb;
9 rows updated.
SQL> select * From t1;
ID1 NAME
---------- ----------
1 A1
1 A1
1 A1
1 A1
2 B2
4 D4
3 C3
4 D4
2 B2
9 rows selected.
----创建唯一索引
SQL> create index ii on t1(id1);
Index created.
SQL> update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb;
update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb
*
ERROR at line 1:
ORA-01779: cannot modify a column which maps to a non key-preserved table
----使用参数/*+ BYPASS_UJVC*/
SQL> update (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb;
9 rows updated.
SQL> select * From t1;
ID1 NAME
---------- ----------
1 A1
1 A1
1 A1
1 A1
2 B2
2 B2
4 D4
3 C3
4 D4
9 rows selected.
SQL> roll
Rollback complete.
SQL> select * From t1;
ID1 NAME
---------- ----------
1 AA
1 BB
1 CC
1 CC
2 B1
2 B2
4 B4
3 B4
4 BC
9 rows selected.
SQL> delete from (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) ;
9 rows deleted.
SQL> select * From t1;
ID1 NAME
---------- ----------
1 AA
1 BB
1 CC
1 CC
2 B1
2 B2
4 B4
3 B4
4 BC
9 rows selected.
SQL> select * From t2;
no rows selected
SQL>
SQL> roll
Rollback complete.
SQL> delete from (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t2 a,t1 b where a.id1=b.id1) ;
9 rows deleted.
SQL> select * From t1;
no rows selected
SQL> roll
Rollback complete.
SQL> select * From t1;
ID1 NAME
---------- ----------
1 AA
1 BB
1 CC
1 CC
2 B1
2 B2
4 B4
3 B4
4 BC
9 rows selected.
SQL> select *From v$version;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
PL/SQL Release 11.2.0.1.0 - Production
CORE 11.2.0.1.0 Production
TNS for 32-bit Windows: Version 11.2.0.1.0 - Production
NLSRTL Version 11.2.0.1.0 - Production
SQL> create table t1 (id1 number,name varchar2(10));
表已创建。
SQL> create table t2 (id1 number,name varchar2(10));
表已创建。
SQL> insert into t1 values(1,'AA')
2 ;
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> insert into t1 values(1,'BB')
2 ;
已创建 1 行。
SQL> insert into t1 values(1,'CC');
已创建 1 行。
SQL> insert into t1 values(2,'B1');
已创建 1 行。
SQL> insert into t1 values(2,'B2');
已创建 1 行。
SQL> insert into t1 values(3,'B4');
已创建 1 行。
SQL> insert into t1 values(4,'B4');
已创建 1 行。
SQL> insert into t1 values(4,'BC');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> SELECT *fROM T1;
ID1 NAME
---------- ----------
1 AA
1 BB
1 CC
2 B1
2 B2
3 B4
4 B4
4 BC
已选择8行。
SQL> insert into t2 values(1,'A1');
已创建 1 行。
SQL> insert into t2 values(2,'B2');
已创建 1 行。
SQL> insert into t2 values(3,'C3');
已创建 1 行。
SQL> insert into t2 values(4,'D4');
已创建 1 行。
SQL> COMMIT;
提交完成。
SQL> select *From t2;
ID1 NAME
---------- ----------
1 A1
2 B2
3 C3
4 D4
SQL> update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb;
update (select a.name namea,b.name nameb from t1 a,t2 b where a.id1=b.id1) set namea=nameb
*
第 1 行出现错误:
ORA-01779: 无法修改与非键值保存表对应的列
SQL> update (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t2 a,t1 b where a.id1=b.id1) set nameb=namea
2 ;
update (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t2 a,t1 b where a.id1=b.id1) set nameb=namea
*
第 1 行出现错误:
ORA-01779: 无法修改与非键值保存表对应的列
SQL> delete (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t2 a,t1 b where a.id1=b.id1) ;
delete (select /*+ BYPASS_UJVC*/ a.name namea,b.name nameb from t2 a,t1 b where a.id1=b.id1)
*
第 1 行出现错误:
ORA-01752: 不能从没有一个键值保存表的视图中删除
用过这样的删除语句么,不知道怎么写才对,不明白到底删除时那个表?
table1是大数据量表,table2是需要删除的数据主键
DELETE /*+ BYPASS_UJVC*/
FROM (SELECT
A.rowid
FROM table2 b, table1 a
WHERE a.rowid=b.pdid);
结论:
(1)要删除数据的表应该放在两个链接表的后面
(2)在/*+ BYPASS_UJVC*/ 是oracle内部的一个参数,是忽略一些检测
(3)在11.2.01版本后不能使用,虽然是bug,但是好像不在修复
(4)
ORACLE要求中间表t2表关联字段唯一是合理的,否则更新删除t1表时,如果t2表有多条记录对应,不知道用哪条记录去更新才好。
但在实际开发时,经常会碰到虽然逻辑上能保证中间t2表的关联字段唯一,但不想,或者无法给它加唯一性约束的情况可以用/*+ BYPASS_UJVC*/