如何从不同的表和视图中删除/插入

时间:2012-11-08 09:54:54

标签: oracle plsql oracle10g execute-immediate

我有一个邪恶的问题。在Oracle 10中,有一对视图和表,其中类似的东西一遍又一遍地完成:

proc_log('DELETE 1');
DELETE FROM table_1;
proc_log('INSERT 1');
INSERT INTO table_1 SELECT * FROM view_1;
proc_log('FINISH 1');

与View / Table 2和3以及4和5 ......以及36相同。

我想做这样的事情:

PROCEDURE proc_import(p_table VARCHAR2) IS
BEGIN
    proc_log('DELETE ' || p_table);
    EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table;
    proc_log('INSERT ' || p_table);
    EXECUTE IMMEDIATE 'INSERT INTO table_' || p_table || ' SELECT * FROM view_' || p_table;
    proc_log('FINISH || p_table);
    COMMIT;
END;

然后调用所有36对的函数。

毫不奇怪,这个东西比硬编码的东西慢约50%。

我的问题:有没有人知道如何加快速度。或者甚至更好,我怎么能让这些东西变得不同但同样优雅呢?


修改

整个东西都是这样构建的:

CREATE OR REPLACE PACKAGE PKG_IMPORT IS
  PROCEDURE proc_log IS BEGIN [funky not important stuff] END;

  PROCEDURE proc_import IS
  BEGIN
      proc_import_table('1', TRUE);
      proc_import_table('2');
      proc_import_table('3');
      proc_import_table('4', TRUE);
      proc_import_table('5');
      ...
      proc_import_table('36');
  END;

  PROCEDURE proc_import(p_table VARCHAR2, p_whole BOOLEAN DEFAULT FALSE) IS
  BEGIN
    proc_log('DELETE ' || p_table);
    IF p_whole THEN
      EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table;
    ELSE
      EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table || ' WHERE business_logic_applies';
    END IF;
    proc_log('INSERT ' || p_table);
    EXECUTE IMMEDIATE 'INSERT INTO table_' || p_table || ' SELECT * FROM view_' || p_table;
    proc_log('FINISH || p_table);
    COMMIT;
  END;
 END PKG_IMPORT;

过程proc_import每晚被一个作业调用一次。所有proc_import_table调用都是硬编码的原因是某些表需要额外的导入信息。

我担心我不能在这里复制/粘贴原始代码,因为我不知道我是否被允许这样做。希望这会有所帮助...

2 个答案:

答案 0 :(得分:2)

首先,如果您没有关于要删除哪些行的任何条件,则可以截断该表。

TRUNCATE TABLE table_1;

TRUNCATE是一个ddl操作,它不会删除行,它只会操纵高水位线,使操作非常快。 但请记住它无法回滚,因为它是DDL。

另一方面,您可以执行直接路径插入,而不是常规路径插入。试试这个:

INSERT /*+ append */ into table_1 select * from view_1;

这将导致Oracle将数据直接写在高水印之上,从而使操作更快。如果您的表格为PARALLEL,它也可能可能

答案 1 :(得分:0)

原始代码可以更快地执行,因为Oracle可以预编译查询,而“执行立即”则无法执行。

您的新代码可能看起来更简洁,但实际上更难阅读。至少,不是传递一个表号,你应该给出完整的表名,否则任何看你的代码的人都必须修改数字的含义。

那就是说,我想我更愿意看到36个删除和36个插入语句 - 远没有那么神秘和更加整洁。如果它有助于缩短过程,你可以将所有这些陈述放入自己的过程中。