【问题标题】:how to call the stored procedure in oracle with the daily scheduled jobs?如何在 oracle 中调用存储过程与每日计划作业?
【发布时间】:2012-11-18 12:40:07
【问题描述】:

我是 Oracle 作业脚本的新手。我编写了一些清除程序来清除所有旧数据并保留最近 3 个月的数据...程序成功执行。当我手动调用时它也可以工作。程序如下:

CREATE OR REPLACE PROCEDURE Archive 
IS

       v_query varchar2(2048);
       v_tablename VARCHAR2(50);
       v_condition varchar2(50);
       TYPE cur_typ IS REF CURSOR;
       c cur_typ;
BEGIN 
    OPEN c for 'select tablename,columnname from pseb.purge_tables';
        FETCH c INTO v_tablename,v_condition;
        LOOP
           EXIT WHEN c%NOTFOUND;
           if(v_tablename ='cfw.DCTBLPERFCUMULATIVEMASTER') then
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB3MAINREG where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB4TODENERG where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERDFCUMULATIVEB5MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB6TODREG where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB7MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB8MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
           else
           begin
               v_query:='delete FROM '|| v_tablename || ' WHERE ' || v_condition||' < sysdate-90';
               execute immediate v_query;
           end;
           end if;
       FETCH c INTO v_tablename,v_condition;
        end LOOP;
        close c;
END; --Procedure

我的JOb脚本如下:

begin
  DBMS_SCHEDULER.CREATE_JOB (
     job_name           =>  'purgeproc_automation',
     job_type           =>  'STORED_PROCEDURE',
     job_action         =>  'call pseb.archive();',
     repeat_interval    =>  'FREQ=DAILY;INTERVAL=2', /* every other day */
     auto_drop          => false,
     enabled            => true,
   comments           =>  'My new job');
end;
/

作业创建成功,但作业状态为失败,不成功。背后的原因是什么?它返回以下错误:

ORA-06550: line 1, column 728:
PLS-00103: Encountered the symbol "PSEB" when expecting one of the following:

   := . ( @ % ;
The symbol ":=" was substituted for "PSEB" to continue.

请指导我解决这个问题...

【问题讨论】:

    标签: plsql oracle11g job-scheduling


    【解决方案1】:

    天啊,你的代码看起来好复杂。首先考虑这种简化:

    CREATE OR REPLACE PROCEDURE Archive 
    IS
       v_query varchar2(2048);
    BEGIN 
        FOR REC IN (select tablename,columnname condition from pseb.purge_tables)
        LOOP
           if(rec.tablename ='cfw.DCTBLPERFCUMULATIVEMASTER') then
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB3MAINREG where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB4TODENERG where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERDFCUMULATIVEB5MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB6TODREG where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB7MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete from cfw.DCTBLPERFDCUMULATIVEB8MAXDEMAN where cumulativeid in (select cumulativeid FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
               v_query:='delete FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
           else
               v_query:='delete FROM '|| rec.tablename || ' WHERE ' || rec.condition||' < sysdate-90';
               execute immediate v_query;
           end if;
        END LOOP;
    END; --Procedure
    

    dbms_job.submit 的替代作业定义:

    declare 
     jid number;
    begin
    dbms_job.submit(
        JOB => jid,
        WHAT => 'pseb.archive;', 
        NEXT_DATE => SYSDATE, 
        INTERVAL  => 'sysdate +2');
    end;
    /
    commit; -- <<--added commit here
    

    检查作业的方法:

    select * from user_jobs;
    

    【讨论】:

    • 您好,谢谢您的简化。我用你的示例代码(使用提交)创建了工作。如何查看已提交作业的详细信息?或者如何验证作业状态是失败还是成功?
    • mmm 我创建了它返回成功执行的 pl/sql 过程的作业。但在 user_jobs 表中没有详细信息
    • 1.你承诺了吗? 2. 你在哪个用户上运行了 pl/sql? 3.你有dba用户权限吗?如果是,请尝试 all_jobs 视图。
    • 哦,太好了,非常感谢您的指导..我当时没有提交,现在已经完成了:)
    • 它运行时没有任何故障吗?您可能需要稍微调整一下 - 间隔 'sysdate+2' 意味着它将在作业结束的时间上增加 2 天(因此运行时间将不断向前推进)。更好的定义是通过给出正确的日期来定义时间 'to_date(2012-12-01 12:00:00,'YYYY-MM-DD HH24:MI:SS') +2' 这样你就可以确定下一个运行日期是你指定的那个。
    【解决方案2】:

    从调度程序作业执行存储过程的最简单方法是更改​​job_type

    休息你可以使用自己的价值观。试试这个并发回结果。

    例子:

    job_type             => 'STORED_PROCEDURE',
    
    job_action           => '"OWNER"."PROCEDURE_NAME"',
    

    【讨论】:

      【解决方案3】:

      您似乎正在混合使用 create_job 和 create 程序的两种不同方式。请务必将您的脚本更改为以下内容:

      begin
        DBMS_SCHEDULER.CREATE_JOB (
           job_name           =>  'purgeproc_automation',
           job_type           =>  'PLSQL_BLOCK',
           job_action         =>  'BEGIN call pseb.archive(); END;',
           repeat_interval    =>  'FREQ=DAILY;INTERVAL=2', /* every other day */
           auto_drop          => false,
           enabled            => true,
         comments           =>  'My new job');
      end;
      /
      

      【讨论】:

      • 那么调度器好像无法访问你的包了。
      • 那我怎样才能完成那个任务呢?
      • 您需要找出调度程序与哪个用户一起运行作业。假设您的包在另一个模式中,您必须确保调度程序用户可以访问创建包的那个模式。抱歉,当我无法访问您的环境时,有点难以更具体。
      • 根据您的指导,我检查了用户是否正在运行调度程序。在 Pseb 模式本身中,一个示例作业正在运行。我在同一个用户中又创建了一项工作来执行相同的过程,但给出了相同的错误。 :(
      猜你喜欢
      • 2018-10-20
      • 2010-09-19
      • 1970-01-01
      • 2023-03-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-01-18
      • 1970-01-01
      相关资源
      最近更新 更多