3

我需要用表 B 中的 2 列更新表 A。(表 A、B 只有 2 列共有 - col1a、co11b ::col2a、col2b

示例脚本:我想用 col1b 更新所有 col1a 值,其中 col2a=col2b

UPDATE a
   SET col1a = (SELECT col1b
                  FROM b
                 WHERE a.col2a = b.col2b)

由于数据量很大,我想定期提交行(比如 5000 条记录)。你能建议一下吗?

4

3 回答 3

4

由于您在问题中显示的查询包含一个子查询,因此这是在表 b 上查找正在更新的每一行。这可能很慢,无论如何更新都是一个足够慢的操作。

根据您的表的设计,我会尝试“更新视图”或合并。UPDATE 的能力取决于是否存在“密钥保留连接”。如果你没有那个,更新将不起作用。如果没有表格的某种 DDL,很难给出正确的答案。

UPDATE (
  select col1a, col1b, col2a, col2b
  from 
    a join b on (a.col2a = b.col2b)
)
set col1a = col1b;

如果 UPDATE 不起作用,您可以尝试 MERGE。这应该在比更新更多的情况下工作。

merge into a
using b on (a.col2a = b.col2b)
when matched then update set a.col1a = b.col1b

这两个语句的优点是它们可以处理整个数据集,而不是一次更新一行。获得更新以使其表现良好可能很困难。

如果有的话,删除列上的任何索引也可能是值得的col1a

于 2013-04-30T02:56:11.500 回答
1

谢谢你们。我得到了解决方案。我正在寻找如下解决方案

        CREATE OR REPLACE PROCEDURE xxwv_cc_token_conversion (
   p_source_table   IN   VARCHAR2,
   p_dest_table     IN   VARCHAR2,
   p_column_name    IN   VARCHAR2,
   p_commit_row     IN   NUMBER
)
IS
   TYPE cv_typ IS REF CURSOR;

   t_cur    cv_typ;

   TYPE token_num IS TABLE OF xxwv_ap_token_test2.token_number%TYPE
      INDEX BY BINARY_INTEGER;

   TYPE row_num IS TABLE OF xxwv_ap_token_test2.row_id%TYPE
      INDEX BY BINARY_INTEGER;

   ex_sql   VARCHAR2 (2000);
   t_num    token_num;
   r_num    token_num;
BEGIN
   OPEN t_cur FOR    ' SELECT token_number, row_id FROM '
                  || p_source_table
                  || ' WHERE ROWNUM < 100';

   LOOP
      FETCH t_cur
      BULK COLLECT INTO t_num, r_num LIMIT p_commit_row;

      ex_sql :=
            'UPDATE '
         || p_dest_table
         || ' SET '
         || p_column_name
         || ' = :1,token_flag = ''Y''  WHERE row_id =  :2';
      FORALL i IN 1 .. t_num.COUNT
         EXECUTE IMMEDIATE ex_sql
                     USING t_num (i), r_num (i);
      COMMIT;
      DBMS_OUTPUT.put_line ('commit finished');
      EXIT WHEN t_cur%NOTFOUND;
   END LOOP;

   CLOSE t_cur;

   COMMIT;
EXCEPTION
   WHEN OTHERS
   THEN
      DBMS_OUTPUT.put_line ('Error occured while updating' || SQLERRM);
END xxwv_cc_token_conversion;
于 2013-05-01T00:04:29.013 回答
0

如果您愿意并且在您的环境中可能的话,您可以

 create table newtable as select .... from oldtable

这将创建一个新表。

然后重新创建索引,重命名两个表并重新创建约束。

于 2013-04-30T01:59:58.867 回答