Câu hỏi hay.
Để mô phỏng tình huống của bạn, tôi đã tạo các bảng mẫu:
SQL> create table t_debtor(id_debtor,header)
2 as
3 select 1, 'Header 1' from dual union all
4 select 2, null from dual union all
5 select 3, 'Header 3' from dual
6 /
Tabel is aangemaakt.
SQL> create table t_element (id_element,id_debtor,insurer)
2 as
3 select 1, 1, 'to be updated' from dual union all
4 select 2, 1, 'to be updated' from dual union all
5 select 3, 2, 'not to be updated' from dual union all
6 select 4, 2, 'not to be updated' from dual union all
7 select 5, 3, 'to be updated' from dual
8 /
Tabel is aangemaakt.
Và với câu lệnh cập nhật hiện tại của bạn, vấn đề trở nên rõ ràng:các giá trị "không được cập nhật" được đặt thành NULL:
SQL> update
2 T_ELEMENT elt
3 set elt.INSURER = (
4 select HEADER
5 from T_DEBTOR debtor
6 where
7 debtor.HEADER is not null
8 and debtor.ID_DEBTOR = elt.ID_DEBTOR)
9 /
5 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2
4 2
5 3 Header 3
5 rijen zijn geselecteerd.
Cách tốt nhất để thực hiện cập nhật này là cập nhật kết hợp của cả hai bảng. Tuy nhiên, có một số hạn chế:
SQL> rollback
2 /
Rollback is voltooid.
SQL> update ( select elt.insurer
2 , dtr.header
3 from t_element elt
4 , t_debtor dtr
5 where elt.id_debtor = dtr.id_debtor
6 and dtr.header is not null
7 )
8 set insurer = header
9 /
set insurer = header
*
FOUT in regel 8:
.ORA-01779: cannot modify a column which maps to a non key-preserved table
Với gợi ý bỏ qua ujvc, chúng ta có thể vượt qua hạn chế này, nhưng không nên làm như vậy trừ khi bạn thực sự biết thực sự chắc chắn rằng t_debtor.id_debtor là duy nhất.
SQL> update /*+ bypass_ujvc */
2 ( select elt.insurer
3 , dtr.header
4 from t_element elt
5 , t_debtor dtr
6 where elt.id_debtor = dtr.id_debtor
7 and dtr.header is not null
8 )
9 set insurer = header
10 /
3 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2 not to be updated
4 2 not to be updated
5 3 Header 3
5 rijen zijn geselecteerd.
Tốt hơn là chỉ thêm một khóa chính. Có thể bạn sẽ có cái này rồi:
SQL> rollback
2 /
Rollback is voltooid.
SQL> alter table t_debtor add primary key (id_debtor)
2 /
Tabel is gewijzigd.
SQL> update ( select elt.insurer
2 , dtr.header
3 from t_element elt
4 , t_debtor dtr
5 where elt.id_debtor = dtr.id_debtor
6 and dtr.header is not null
7 )
8 set insurer = header
9 /
3 rijen zijn bijgewerkt.
SQL> select * from t_element
2 /
ID_ELEMENT ID_DEBTOR INSURER
---------- ---------- -----------------
1 1 Header 1
2 1 Header 1
3 2 not to be updated
4 2 not to be updated
5 3 Header 3
5 rijen zijn geselecteerd.
Trân trọng, Rob.