Here is a short demonstration of this fix control.
SQL> select banner_full from v$version; BANNER_FULL ---------------------------------------------------------------------------------------------------- Oracle Database 19c Enterprise Edition Release 19.0.0.0.0 - Production Version 19.10.0.0.0 SQL> SQL> col fix_control for a90 SQL> SQL> select xmltype.createxml(cursor( 2 select * 3 from v$system_fix_control 4 where bugno = 19138896)) fix_control 5 from dual; FIX_CONTROL ------------------------------------------------------------------------------------------ <?xml version="1.0"?> <ROWSET> <ROW> <BUGNO>19138896</BUGNO> <VALUE>0</VALUE> <SQL_FEATURE>QKSFM_DML_19138896</SQL_FEATURE> <DESCRIPTION>allow update of join view without key preserved property</DESCRIPTION> <EVENT>0</EVENT> <IS_DEFAULT>1</IS_DEFAULT> <CON_ID>3</CON_ID> </ROW> </ROWSET> SQL> SQL> create table t1 ( 2 pk_col int, 3 t1_col varchar2(30)); Table created. SQL> SQL> create table t2 ( 2 pk_col int, 3 t2_col varchar2(30)); Table created. SQL> SQL> insert into t1 values (1, 't1_1'); 1 row created. SQL> insert into t1 values (2, 't1_2'); 1 row created. SQL> SQL> insert into t2 values (2, 't2_2'); 1 row created. SQL> insert into t2 values (3, 't2_3'); 1 row created. SQL> SQL> commit; Commit complete. SQL> SQL> select * from t1; PK_COL T1_COL ---------- ------------------------------ 1 t1_1 2 t1_2 SQL> SQL> select * from t2; PK_COL T2_COL ---------- ------------------------------ 2 t2_2 3 t2_3Let us try to update all rows in
T2
with the matching value from T1
:
SQL> update (select t2_col, t1_col 2 from t1, t2 3 where t2.pk_col = t1.pk_col) 4 set t2_col = t1_col; set t2_col = t1_col * ERROR at line 4: ORA-01779: cannot modify a column which maps to a non key-preserved tableCannot do that. BYPASS_UJVC does not work either.
SQL> update --+ bypass_ujvc 2 (select t2_col, t1_col 3 from t1, t2 4 where t2.pk_col = t1.pk_col) 5 set t2_col = t1_col; set t2_col = t1_col * ERROR at line 5: ORA-01779: cannot modify a column which maps to a non key-preserved tableNow with fix control 19138896:
SQL> update --+ opt_param('_fix_control' '19138896:1') 2 (select t2_col, t1_col 3 from t1, t2 4 where t2.pk_col = t1.pk_col) 5 set t2_col = t1_col; 1 row updated. SQL> SQL> select * 2 from t2; PK_COL T2_COL ---------- ------------------------------ 2 t1_2 3 t2_3 SQL> SQL> roll Rollback complete.If I try to add a duplicate row to
T1
making this update non-deterministic, so that there is an attempt to update one row from T2
more than once, I get an error:
SQL> insert into t1 values (2, 't1_22'); 1 row created. SQL> update --+ opt_param('_fix_control' '19138896:1') 2 (select t2_col, t1_col 3 from t1, t2 4 where t2.pk_col = t1.pk_col) 5 set t2_col = t1_col; from t1, t2 * ERROR at line 3: ORA-30926: unable to get a stable set of rows in the source tables
Conclusion
Altrough I generally prefer either rewriting such statements to MERGE or adding missing constraints, the fix control 19138896 brings another option to the table. It also has certain advantages, to name a few:- There is no need to rewrite the query. The fix control can be added through an SQL patch, for example.
- The fix control can be set at the session or instance levels.
Комментариев нет:
Отправить комментарий
Примечание. Отправлять комментарии могут только участники этого блога.