使用其他表中的条件更新表的最有效方法?

时间:2013-04-27 11:58:54

标签: sql sql-server oracle

在条件中更新需要外键(到其他表)的表的最有效/最快的方法是什么?

我通常这样做:

UPDATE table1 WHERE table1_id in (SELECT table1_id FROM table2 WHERE whatever)

但我想弄清楚是否有一种更有效的方法来避免子查询。

我想知道的原因是因为我昨天才知道没有像这样的子查询就可以删除:

DELETE t1 FROM table1 t1
JOIN table2 t2 ON t1.table1_id = t2.table1_id 
WHERE whatever

但我无法弄清楚如何将相同的JOIN技术应用于UPDATE语句

3 个答案:

答案 0 :(得分:2)

试试这个 -

<强> MS-SQL:

UPDATE t
SET column_id = t2.column_id
FROM table1 t
JOIN table2 t2 ON t.table1_id = t.table2_id 
WHERE whatever

<强>甲骨文:

UPDATE (
    SELECT table1.value as OLD, table2.CODE as NEW
    FROM table1
    JOIN table2 ON table1.value = table2.DESC
    WHERE anything
) t
SET t.OLD = t.NEW

答案 1 :(得分:0)

UPDATE (
  SELECT t1.*
  FROM table1 t1
  JOIN table2 t2 ON t1.table1_id = t2.table1_id 
  WHERE whatever
) t
SET t.col = ...

答案 2 :(得分:0)

在Oracle中,您可以根据可从无限数量的表中获取的游标执行批量更新。这是最快的更新方式。

declare
    cursor cur_cur
    IS
    select t1.rowid row_id, t2.column1, t2.column2
    FROM table1 t1
    JOIN table2 t2 ON t1.table1_id = t2.table1_id 
    WHERE whatever
    order by row_id
    ;

    type type_rowid_array is table of rowid index by binary_integer;
    type type_column1_array is table of table1.column1%type;
    type type_column2_array is table of table1.column2%type;

    arr_rowid type_rowid_array;
    arr_column1 type_column1_array;
    arr_column2 type_column2_array;

    v_commit_size number := 10000;

begin
    open cur_cur;

    loop
        fetch cur_cur bulk collect into arr_rowid, arr_column1, arr_column2 limit v_commit_size;

        forall i in arr_rowid.first .. arr_rowid.last
            update table1 tab
            SET    tab.column1 = arr_column1(i)
            ,      tab.column2 = arr_column2(i)
            where  tab.rowid = arr_rowid(i)
            ;

        commit;
        exit when cur_cur%notfound;

    end loop;

    close cur_cur;
    commit;

exception
  when others
    then rollback;
         raise_application_error(-20000, 'Fout bij uitvoeren update van table1(column1,column2) - '||sqlerrm);

end;