使用Oracle的DBMS_JOB包并行执行存储过程中独立插入任务的完整示例,Oracle并行执行独立任务程序

一、关键实现说明:

  1. 每个DBMS_JOB.SUBMIT调用创建一个独立后台作业25
  2. 通过WHAT参数指定要执行的PL/SQL代码块5
  3. NEXT_DATE设为SYSDATE使作业立即执行5
  4. RUN方法强制立即启动作业实现并行5
  5. 需要COMMIT确保作业提交到作业队列5

监控方法:

  1.查询USER_JOBS视图查看作业状态5

  2.使用DBMS_JOB.REMOVE删除已完成作业5

  3.通过DBA_JOBS_RUNNING查看当前运行作业5

注意事项:

  1. 需要具有CREATE JOB系统权限5
  2. 并行作业会消耗更多系统资源1
  3. 建议在低业务峰期执行大批量操作1
  4. 表空间需预留足够空间容纳并行插入4
  5. 考虑对源表temp_sales按year列分区提升查询效率

二、DBMS_JOB.SUBMIT参数详解

  1. what参数‌

    • 支持任意有效的PL/SQL代码,常见形式包括:
      • 直接调用存储过程:'my_procedure;'
      • 执行匿名块:'BEGIN update_table; COMMIT; END;'
    • 必须显式包含事务控制语句(如COMMIT),否则可能导致锁未释放58
  2. next_date参数‌

    • 典型时间表达式示例:
      sqlCopy Code
       
      -- 每天凌晨1点执行 next_date => TRUNC(SYSDATE) + 1 -- 每5分钟执行一次 next_date => SYSDATE + 5/(24*60)
    • 若未指定时间,默认使用SYSDATE立即启动35
  3. interval参数‌

    • 常用间隔规则:
      表达式含义
      'SYSDATE + 1' 每天执行
      'TRUNC(SYSDATE) + 1 + 3/24' 每天凌晨3点执行
      'NULL' 仅执行一次
    • 表达式每次执行后重新计算,需避免复杂运算导致性能问题8
-- 创建测试表
CREATE TABLE sales_data_2023 (id NUMBER, amount NUMBER, sale_date DATE);
CREATE TABLE sales_data_2024 (id NUMBER, amount NUMBER, sale_date DATE);
CREATE TABLE temp_sales (id NUMBER, amount NUMBER, sale_date DATE, year NUMBER);

-- 创建存储过程(包含3个独立插入操作)
CREATE OR REPLACE PROCEDURE proc_parallel_insert AS
BEGIN
  -- 插入操作1
  INSERT INTO sales_data_2023 
  SELECT id, amount, sale_date FROM temp_sales WHERE year = 2023;
  
  -- 插入操作2
  INSERT INTO sales_data_2024 
  SELECT id, amount, sale_date FROM temp_sales WHERE year = 2024;
  
  -- 操作3(示例性操作)
  UPDATE sales_stats SET last_updated = SYSDATE;
END;
/

-- 使用DBMS_JOB提交并行任务
DECLARE
  job1 NUMBER;
  job2 NUMBER;
  job3 NUMBER;
BEGIN
  -- 提交第一个插入任务
  DBMS_JOB.SUBMIT(
    job  => job1,
    what => 'BEGIN INSERT INTO sales_data_2023 SELECT id, amount, sale_date FROM temp_sales WHERE year = 2023; COMMIT; END;',
    next_date => SYSDATE,
    interval  => NULL
  );
  
  -- 提交第二个插入任务
  DBMS_JOB.SUBMIT(
    job  => job2,
    what => 'BEGIN INSERT INTO sales_data_2024 SELECT id, amount, sale_date FROM temp_sales WHERE year = 2024; COMMIT; END;',
    next_date => SYSDATE,
    interval  => NULL
  );
  
  -- 提交第三个任务(非插入操作示例)
  DBMS_JOB.SUBMIT(
    job  => job3,
    what => 'BEGIN UPDATE sales_stats SET last_updated = SYSDATE; COMMIT; END;',
    next_date => SYSDATE,
    interval  => NULL
  );
  
  COMMIT;
  
  -- 立即启动作业
  DBMS_JOB.RUN(job1);
  DBMS_JOB.RUN(job2);
  DBMS_JOB.RUN(job3);
  
  DBMS_OUTPUT.PUT_LINE('已提交作业ID: ' || job1 || ', ' || job2 || ', ' || job3);
END;
/

 

posted @ 2025-05-23 17:24  ARYOUOK  阅读(133)  评论(0)    收藏  举报