簡體   English   中英

根據其他表中的列批量更新多個列

[英]Bulk Update for multiple columns based on columns from other table

我正在嘗試在 Oracle 中進行批量更新。 該操作涉及根據另一個表中的列值更新目標表中的數百萬條記錄。場景是這樣的。

我有 2 張桌子:

T1(來源)

t1_col1 t1_col2 t1_col3 t1_col4 t1_col5

T2(目標)

t2_col1 t2_col2 t2_col3 t2_col4 t2_col5 t2_col6

我需要做這樣的更新:

update t1
set t2_col1 = t1_col1,
    t2_col2 = t1_col2,
    t2_col3 = sysdate
where t2_col4 = t1_col4
and t2_col5 = t1_col5
and t2_col6 = null

如何對包含數百萬條記錄的多個列實現上述更新。 通過論壇,我知道這應該使用批量收集、cursor、限制等來完成。不過,我無法提出基於此的查詢。 感謝你的幫助。

百萬列的更新總是很慢。 無論您是使用 UPDATE 還是 BULK COLLECT 執行此操作。 最快的方法是創建為 SELECT。

例如,人力資源計划:

創建目標表 EMP,例如作為員工表的副本:

create table emp as select * from employees; update emp set salary = salary * 2;

創建第三個臨時表,使用您更新的新值,在這里我更改 SALARY 列

create  table emp_new as  SELECT
    emp.employee_id,
    emp.first_name,
    emp.last_name,
    emp.email,
    emp.phone_number,
    emp.hire_date,
    emp.job_id,
    e.salary,
    emp.commission_pct,
    emp.manager_id,
    emp.department_id FROM
    employees e, emp WHERE emp.employee_id = e.employee_id;

刪除原始目標表:

create table emp_arch as select * from emp; -- you can want to archive data drop table emp;

將第三個表重命名為目標表名

rename  emp_new to emp;

就是這樣,這應該是最快的方法。 您必須記住,您應該將約束和索引添加到新表。

我曾經比較過如何使用不同的方法加載數據,所以如果你有興趣可以檢查一下。 在 並且有腳本。

https://how2ora-en.blogspot.com/2020/03/loading-data-sql-vs-forall-perf-tests.html

如果您想使用批量收集,它可能如下所示:

declare

type tabEmp is table of employees%rowtype;
tEmp tabEmp;

bulk_errors       exception;
pragma exception_init(bulk_errors, -24381); 

nErrCnt number;
n_errcode    number;
v_msg    varchar2(4000);
n_idx    number;

cursor cur is select * from employees;
begin

open cur;
loop

    fetch cur bulk collect into tEmp;
    exit when tEmp.count =0;
   
    BEGIN
     forall i in 1..tEmp.count 
     
     update emp set salary = tEmp(i).salary;
    
    exception when bulk_errors then    
                nErrCnt:= sql%bulk_exceptions.count;
                            for i in 1 .. nErrCnt
                            loop
                                n_errcode := sql%bulk_exceptions(i).error_code;
                                v_msg   := sqlerrm(-n_errcode);
                                n_idx   := sql%bulk_exceptions(i).error_index;
                                
                                  dbms_output.put_line(n_errcode);
                            end loop;
    end;
end loop;

close cur;
end;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM