Stored procedures 优化存储过程以替换游标

Stored procedures 优化存储过程以替换游标,stored-procedures,oracle10g,Stored Procedures,Oracle10g,我有一个存储过程,它使用游标获取一些数据,然后在该游标上迭代以更新主表中的条目。我曾想过用临时表替换光标,但实际上没有帮助。欢迎任何建议。这是我为测试创建的示例过程 我的程序如下: **CREATE OR REPLACE PROCEDURE SYSTEM.modify_process_hr_change_log IS v_ddl VARCHAR2 (1000); v_dropddl VARCHAR2 (1000); v_execsql VARCHAR2 (1

我有一个存储过程,它使用游标获取一些数据,然后在该游标上迭代以更新主表中的条目。我曾想过用临时表替换光标,但实际上没有帮助。欢迎任何建议。这是我为测试创建的示例过程

我的程序如下:

**CREATE OR REPLACE PROCEDURE SYSTEM.modify_process_hr_change_log
IS
   v_ddl       VARCHAR2 (1000);
   v_dropddl   VARCHAR2 (1000);
   v_execsql   VARCHAR2 (1000);
   v_dt_max    VARCHAR2 (1000)
      :=    EXTRACT (HOUR FROM CURRENT_TIMESTAMP)
         || ':'
         || EXTRACT (MINUTE FROM CURRENT_TIMESTAMP)
         || ':'
         || EXTRACT (SECOND FROM CURRENT_TIMESTAMP);
BEGIN
--   SAVEPOINT mdfy_process_hr_change_log;
   BEGIN
      v_dropddl := 'DROP TABLE temp_AttuidChange';
      v_ddl :=
         'CREATE TABLE temp_AttuidChange
  AS (select
sup.id as id,
sup.name as name,
sup.role as role,
sup.technology as technology
from
main hr,
secondary sup
where
 sup.id=hr.id) ';
      EXECUTE IMMEDIATE v_ddl;
      COMMIT;
   END;
--dbms_output.put_line(dbms_utility.get_time);
   -- update records in main tables from the temporary table
   EXECUTE IMMEDIATE ' UPDATE main t1
      SET (t1.ID, t1.NAME, t1.ROLE, t1.technology) =
             (SELECT t2.ID, t2.NAME, t2.ROLE, t2.technology
                FROM temp_AttuidChange t2
               WHERE t2.ID = t1.ID)
    WHERE EXISTS (SELECT *
                    FROM temp_attuidchange
                   WHERE temp_attuidchange.ID = t1.ID)';
   COMMIT;
   EXECUTE IMMEDIATE v_dropddl;
--dbms_output.put_line(EXTRACT(HOUR FROM  CURRENT_TIMESTAMP) || ':' ||EXTRACT(MINUTE FROM  CURRENT_TIMESTAMP)|| ':' ||EXTRACT(SECOND FROM  CURRENT_TIMESTAMP));
END;
/**
使用游标的原始过程

CREATE OR REPLACE PROCEDURE SYSTEM.process_hr_change_log1
IS
cursor cur_attuid_change is
select
sup.id as id,
sup.name as name,
sup.role as role,
sup.technology as technology
from
main hr,
secondary sup
where
 sup.id=hr.id;

BEGIN


   -- update records in main tables from the cursor
   for rec_attuid_change in cur_attuid_change loop

    update main t1
    set    t1.id    = rec_attuid_change.id,
    t1.name    = rec_attuid_change.name,
   t1.ROLE=rec_attuid_change.role,
   t1.technology=rec_attuid_change.technology
    where    t1.id = rec_attuid_change.id;
    commit;

    update main1 t1
    set    t1.id    = rec_attuid_change.id,
    t1.name    = rec_attuid_change.name,
   t1.ROLE=rec_attuid_change.role,
   t1.technology=rec_attuid_change.technology
    where    t1.id = rec_attuid_change.id;
    commit;

    update main2 t1
    set    t1.id    = rec_attuid_change.id,
    t1.name    = rec_attuid_change.name,
   t1.ROLE=rec_attuid_change.role,
   t1.technology=rec_attuid_change.technology
    where    t1.id = rec_attuid_change.id;
    commit;
   end loop;


END;
/

如果要使用这种方法,应该使用全局临时表,而不是动态创建普通表。动态SQL并没有让生活变得更轻松。也许你应该关注一个相关的更新,而不是在一个循环中进行大量的单独更新;还是使用集合和批量更新?不过,为您重写代码太宽泛了。@AlexPoole:我对不同的表有不同的更新查询。这只是一个示例。因此,可能在一次相关更新中不可能做到这一点,可能我在这方面做得不太好。那么全局临时表究竟有多大帮助!!