Scheduling an OWB 9.0.4/9.2/10.1 Mapping or Process Flow Using DBMS_JOB

April 28th, 2005 by Mark Rittman

To schedule an OWB mapping or process flow to run at a set time, and
optionally to run again after a set interval, without having to deploy it to OEM:

First, log on as the Runtime Repository owner, and run the following script
to create a function called RUN_OWB_JOB. This is a slightly modified version of
the RUN_MY_OWB_STUFF.SQL script downloadable from OTN at

http://www.oracle.com/technology/sample_code/products/warehouse/files/run_my_owb_stuff.sql

create or replace function run_owb_job
              ( p_repos_owner in varchar2 default null
              , p_location_name in varchar2 default null
              , p_task_type in varchar2 default null
              , p_task_name in varchar2 default null
              , p_system_params in varchar2 default '","'
              , p_custom_params in varchar2 default '","'
              , p_oem_friendly in number default 0
              ) return number
is

  l_oem_style          boolean := case (p_oem_friendly)
                                        when 0 then false
                                        else true
                                        end ;
  l_audit_execution_id number;                                  -- Audit Execution Id
  l_audit_result       number := wb_rt_api_exec.RESULT_FAILURE; -- Result Code
  l_audit_result_disp  varchar2(64) := 'FAILURE';               -- Result Display Code

  l_task_type_name     varchar2(64);                            -- Task Type Name
  l_task_type          varchar2(64);                            -- Task Type
  l_task_name          varchar2(64);                            -- Task Name
  l_location_name      varchar2(64);                            -- Location Name

  l_return number ;

  procedure override_input_parameter
  (
    p_audit_execution_id in number,
    p_parameter_name in varchar2,
    p_value in varchar2,
    p_parameter_kind in number
  )
  is
    l_parameter_kind varchar2(64);
  begin

    if p_parameter_kind = wb_rt_api_exec.PARAMETER_KIND_SYSTEM
    then
      l_parameter_kind := 'SYSTEM';
    else
      l_parameter_kind := 'CUSTOM';
    end if;

    dbms_output.put_line('|  ' || p_parameter_name || '%' || l_parameter_kind || '=' || '''' || p_value || '''');

    wb_rt_api_exec.override_input_parameter
    (
      p_audit_execution_id,
      p_parameter_name,
      p_value,
      p_parameter_kind
    );

  end;

  procedure override_input_parameters
  (
    p_audit_execution_id in number,
    p_parameters varchar2,
    p_parameter_kind in number
  )
  is
    l_anchor_offset number := 1;
    l_start_offset number := 1;
    l_equals_offset number;
    l_comma_offset number;
    l_value_offset number;
    l_esc_offset number;
    l_esc_count number;
    l_esc_char varchar2(4);
    l_parameter_name varchar2(4000);
    l_parameter_value varchar2(4000);

    function strip_escape
    (
      p_escapedString varchar2
    )
    return varchar2
    is
      l_strippedString varchar2(4000);
      l_a_char varchar2(4);
      l_b_char varchar2(4);
      l_strip_offset number := 1;
    begin
      loop
        exit when p_escapedString is null or l_strip_offset > length(p_escapedString);
        l_a_char := SUBSTR(p_escapedString, l_strip_offset, 1);
        if l_strip_offset = length(p_escapedString)
        then
          l_strippedString := l_strippedString || l_a_char;
          exit;
        else
          if l_a_char = '\'
          then
            l_b_char := SUBSTR(p_escapedString, l_strip_offset + 1, 1);
            if l_b_char = '\' or l_b_char = ','
            then
              l_strippedString := l_strippedString || l_b_char;
              l_strip_offset := l_strip_offset + 1;
            end if;
          else
            l_strippedString := l_strippedString || l_a_char;
          end if;
        end if;
        l_strip_offset := l_strip_offset + 1;
      end loop;

      return l_strippedString;
    end;

  begin
    loop
      l_equals_offset := INSTR(p_parameters, '=', l_start_offset);

      exit when l_equals_offset = 0;

      l_start_offset := l_equals_offset + 1;
      loop
        l_comma_offset := INSTR(p_parameters, ',', l_start_offset);

        if l_comma_offset = 0
        then
          l_comma_offset := length(p_parameters) + 1;
          exit;
        else
          l_esc_count := 0;
          l_esc_offset := l_comma_offset - 1;
          loop
            l_esc_char := SUBSTR(p_parameters, l_esc_offset, 1);
            exit when l_esc_char != '\';
            l_esc_count := l_esc_count + 1;
            l_esc_offset := l_esc_offset - 1;
          end loop;

          if MOD(l_esc_count, 2) != 0
          then
            l_start_offset := l_comma_offset + 1;
          else
            exit;
          end if;
        end if;
      end loop;

      l_parameter_name := LTRIM(RTRIM(SUBSTR(p_parameters, l_anchor_offset, l_equals_offset - l_anchor_offset)));
      l_parameter_value := strip_escape(SUBSTR(p_parameters, l_equals_offset + 1, l_comma_offset - (l_equals_offset + 1)));

      -- Override Input Parameter
      override_input_parameter(p_audit_execution_id, l_parameter_name, l_parameter_value, p_parameter_kind);

      exit when l_comma_offset >= length(p_parameters)-1;

      l_start_offset := l_comma_offset + 1;
      l_anchor_offset := l_start_offset;

    end loop;
  end;

  procedure override_custom_input_params
  (
    p_audit_execution_id in number,
    p_parameters varchar2
  )
  is
    l_parameter_kind number := wb_rt_api_exec.PARAMETER_KIND_CUSTOM;
  begin
    override_input_parameters(p_audit_execution_id, p_parameters, l_parameter_kind);
    null;
  end;

  procedure override_system_input_params
  (
    p_audit_execution_id in number,
    p_parameters varchar2
  )
  is
    l_parameter_kind number := wb_rt_api_exec.PARAMETER_KIND_SYSTEM;
  begin
    override_input_parameters(p_audit_execution_id, p_parameters, l_parameter_kind);
    null;
  end;

begin

  execute immediate ('alter session set current_schema = ' || p_repos_owner) ;

  --
  -- Initialize Return Code
  --
  l_return := wb_rt_api_exec.RESULT_FAILURE;

  --
  -- Import Parameters
  --
  dbms_output.put_line('Stage 1: Decoding Parameters');
  l_task_type_name := p_task_type ;
  if UPPER(l_task_type_name) = 'PLSQL'
  then
    l_task_type := 'PLSQL';
  elsif UPPER(l_task_type_name) = 'SQL_LOADER'
  then
    l_task_type := 'SQLLoader';
  elsif UPPER(l_task_type_name) = 'PROCESS'
  then
    l_task_type := 'ProcessFlow';
  else
    l_task_type := l_task_type_name;
  end if;
  l_task_name := p_task_name ;
  l_location_name := p_location_name ;
  dbms_output.put_line('|  location_name=' || l_location_name);
  dbms_output.put_line('|  task_type=' || l_task_type);
  dbms_output.put_line('|  task_name=' || l_task_name);

  --
  -- Decode Parameters
  --
  begin
    --
    -- Prepare Execution
    --
    dbms_output.put_line('Stage 2: Opening Task');
    l_audit_execution_id := wb_rt_api_exec.open(l_task_type, l_task_name, l_location_name);
    dbms_output.put_line('|  l_audit_execution_id=' || to_char(l_audit_execution_id));

    commit;

    --
    -- Override Parameters
    --
    dbms_output.put_line('Stage 3: Overriding Parameters');
    override_system_input_params(l_audit_execution_id, p_system_params);
    override_custom_input_params(l_audit_execution_id, p_custom_params);

    --
    -- Execute
    --
    dbms_output.put_line('Stage 4: Executing Task');
    l_audit_result := wb_rt_api_exec.execute(l_audit_execution_id);
    if l_audit_result = wb_rt_api_exec.RESULT_SUCCESS
    then
      l_audit_result_disp := 'SUCCESS';
    elsif l_audit_result = wb_rt_api_exec.RESULT_WARNING
    then
      l_audit_result_disp := 'WARNING';
    elsif l_audit_result = wb_rt_api_exec.RESULT_FAILURE
    then
      l_audit_result_disp := 'FAILURE';
    else
      l_audit_result_disp := 'UNKNOWN';
    end if;
    dbms_output.put_line('|  l_audit_result=' || to_char(l_audit_result) || ' (' || l_audit_result_disp || ')');

    -- Finish Execution
    dbms_output.put_line('Stage 5: Closing Task');
    wb_rt_api_exec.close(l_audit_execution_id);

    commit;

    dbms_output.put_line('Stage 6: Processing Result');
    if l_oem_style
    then
      if l_audit_result = wb_rt_api_exec.RESULT_SUCCESS
      then
        l_return := 0;
      elsif l_audit_result = wb_rt_api_exec.RESULT_WARNING
      then
        l_return := 0;
      else
        l_return := l_audit_result;
      end if;
    else
      l_return := l_audit_result;
    end if;
    dbms_output.put_line('|  exit=' || to_char(l_return));
  exception
    when no_data_found
    then
      raise_application_error(-20001, 'Task not found - Please check the Task Type, Name and Location are correct.');
    end;

  return l_return ;

end;
/

Then, grant EXECUTE on this function to the schema that will submit the job:

SQL> grant execute on run_owb_job to rt92;

Grant succeeded.

Then, assuming your Runtime Repository schema is RTR92, your job you wish to
run is a process flow and is in the WH_PROC_LOC location, the process flow is
called LOAD_T_TIME and you want it to run on 25-APR-2005 at 17:20, run the
following script

declare jobno number;
begin
dbms_job.submit(jobno, 'declare res number; begin res := rtr92.run_owb_job(''rtr92'',
	''WH_PROC_LOC'',''PROCESS'',''LOAD_T_TIME''); end;', to_date('25-APR-2005 17:20','DD-MON-YYYY HH24:MI'));
commit;
end;
/

You can check what jobs are due to run by querying DBA_JOBS:

select * from all_jobs;

If you want the job to run on a regular basis, you can put an interval after
the scheduled time to run, such as:

declare jobno number;
begin
dbms_job.submit(jobno, 'declare res number; begin res := rtr92.run_owb_job(''rtr92'',
	''WH_PROC_LOC'',''PROCESS'',''LOAD_T_TIME''); end;', to_date('25-APR-2005 17:20','DD-MON-YYYY HH24:MI'),'SYSDATE +1');
commit;
end;

Note that the second parameter in the DBMS_JOB call is an anonymous PL/SQL
block that calls the RUN_OWB_JOB function. The PL/SQL that is being executed is:

declare res number;
begin
   res := rtr92.run_owb_job('rtr92','WH_PROC_LOC','PROCESS','LOAD_SALES');
end;

Also if you are using Oracle Database 10g you might want to replace DBMS_JOB
with DBMS_SCHEDULER, which comes with a number of new features and is the “native” scheduling service in OWB “Paris”.

Comments

  1. Nigel Thomas Says:

    Mark – You’ve changed the name of the function to RUN_OWB_JOB but the rest of the instructions continue to refer to (rtr92.)run_my_owb_stuff.
    Cheers Nigel

  2. Mark Says:

    Thanks Nigel, I’ve corrected the article now. We changed the name of the function (the only change we made) as the “RUN_MY_OWB_STUFF” name wasn’t considered “corporate standard”. I had both versions installed on my laptop, hence the fact the old function name worked. Thanks for pointing it out.
    mark

  3. Damasio Nunes Says:

    Hi Mark,
    I used your run_owb_job function in a loop for running process flows from different packages. It runs the first process flow, but it can’t find the next process that’s located in another package in the same reppository and in the same location. How could i resolve this problem?
    Thanks in advance
    Damasio Nunes

  4. Dam sio Nunes Says:

    Hi again,
    The jobs that i tried is just sending an e-mail from different packages, the mail is successufly sent but still the function returns a warning and in my loop i stoped with warnings. Continuing the loop even with warnings i can run jobs from different packages. Do you have any ideia about why the job returns with warnings?
    Best regards.

  5. Mark Says:

    Hi Damasio,
    Unfortunately I didn’t write the script, I changed the name of the package to make it more “naming standards friendly” and stripped out the comments at the start. If you download the original version at http://www.oracle.com/technology/sample_code/products/warehouse/files/run_my_owb_stuff.sql and take a look at the comments at the start of the script, you might be able to figure out what’s going wrong.

  6. Neo Says:

    Hi,
    I am a new bie to OWB. Can u give some where i can learn from the beginning to the end. I need to write ETL scripts for loading tables from five DB into one DWH with some complex business rules.

  7. vikas Says:

    Hello,

    I am new to owb.
    We are trying to get a value from one table and based on that run Map1 or Map2 in a process flow.

    Now the problem is, we tried using Sqlplus script, enabled the property on server – Runtime.properties

    property.RuntimePlatform.0.NativeExecution.SQLPlus.security_constraint = NATIV_JAVA

    still its not taking this path, simply going to the else part and exectuing mapping in that flow.

    Has anyone come accross similar situation, if so please suggest what should we do in this case.

    Or is there any other way to handle it.

    Thanks,

Website Design & Build: tymedia.co.uk