Как вызвать процедуру внутри тела пакета, используя SQLPLUS в Oracle 11g - PullRequest
0 голосов
/ 14 декабря 2018

Я использую Oracle 11g.Процедура ниже преобразует текстовый файл в файл xls.Я хочу вызвать эту процедуру через SQLPLUS.Имя тела пакета - "VMDB_OAS_doc_utils", а имя процедуры - "Convert_Multi_Sheet". Параметры - source_path, target_path, and opts.Расположение каталога txt файла: /isweb/www/ss/issapt/vmdb/adhoc_reports/vwar_444026.txt. Как мне написать скрипт, который вызывает эту процедуру, чтобы он преобразовывал этот txt файл в файл xls?Вот код для процедуры ниже:

---------------------------
--- This procedure allows a tab-delimited file to be converted 
--  into a multi-sheet MS-Excel file. The dbsm_scheduler is used to schedule a server side 
--  job to do the conversion. Scheduler tables/views are queried for status and this routine
--  busy waits for the process to complete. Afterwards error return status is returned in the 
--  err_msg parameter. After more investigation, it was determined that java would be a superior
--  approach, primarily because it provides for finer granularity in controlling execution priviliges.
--  However, it was too late to make the 951 release.
---
--- @@param source_path - a string containing the full file path of the source.
--- @@param target_path - a string containing the full target file path. 
---
--- @@param opts - a string containing the options to the sv2xls.pl 
---    command as entered as if at a terminal (including the dash).
---
--- @@return err_msg - a string containing error message.  Empty otherwise.
---------------------------
   procedure Convert_Multi_Sheet (
      source_path in varchar2,
      target_path in out varchar2,
      opts in varchar2 := NULL,
      err_msg      out varchar2
   ) is
      result boolean;  
      -- The command to run
      command varchar2(32767):= vmdb_web.get_var_val('VMDB_RUNLIB');
      -- The name of the job, generated 
      jobname varchar2(40);
      number_of_arguments PLS_INTEGER :=2;
      argument_position PLS_INTEGER:= 1;
      l_opts_array vmdb_oas_utils.ISAC_ident_arr;
      -- Get the completion status of the passed jobname. 
      -- Will time out after six hours. 
      -- 
      -- @@param jobname the job to get completions status from.
      -- @@returns any error message caused by running the job or null if no error was detected.
      --
      function get_completion_status(jobname varchar2) return varchar2 is
       result varchar2(32767):='RUNNING'; -- Status
       stop_date date:= sysdate + 6/24; -- Stop the date after six hours if it hasn't quit yet
      begin
        while result = 'RUNNING' and sysdate < stop_date loop
      begin
          SELECT upper(STATE) into result FROM all_scheduler_jobs where job_name=jobname ;
          -- The job may return successfully if one of these occurs.
          if result in ('SCHEDULED', 'RUNNING', 'RETRY SCHEDULED') then
          result:= 'RUNNING';
          end if;
         exception
          when no_data_found then
            -- Job has completed. Normal execution returns null (no error).
        result:= null;
     end;
    end loop;
    if nvl(result, '<NULL>') = '<NULL>' and sysdate >= stop_date then
      result:= 'Error: process has timed out!';
    else
      begin
        SELECT upper(STATUS) into result FROM ALL_SCHEDULER_JOB_RUN_DETAILS where job_name=jobname;
        -- Successful statuses
        if result = 'SUCCEEDED'  or result = 'COMPLETED'  then
          result:= null;
        else 
          select status||chr(10)||'ERROR#:'||ERROR#||chr(10)||'INFO:'|| ADDITIONAL_INFO into result from ALL_SCHEDULER_JOB_RUN_DETAILS
            where job_name=jobname;
        end if;
       exception
        when no_data_found then
          result:= 'No data found.';
       end;
    end if;
    return result;
  end get_completion_status;
   begin
  if regexp_like(target_path, '*.xlsx', 'i') then
     command:= command||'/sv2xlsx.pl';
     jobname := DBMS_SCHEDULER.GENERATE_JOB_NAME(prefix=>'sv2xlsx$_');
  else
     command:= command||'/sv2xls.pl';
     jobname := DBMS_SCHEDULER.GENERATE_JOB_NAME(prefix=>'sv2xls$_');
  end if;
  -- Debug - only prints out when serveroutput is set on
  dbms_output.put_line('jobname is '|| jobname);
  dbms_output.put_line('command is '|| command);
  if nvl(opts, '<NULL>') != '<NULL>' then
    -- options?
    l_opts_array:= vmdb_oas_utils.varchar_2_ident_array (opts, '-');
    -- ASR 115302 - Scheduler is choking on multiple dash (-) args in
    --  single argument position - so split them into seperate args.
    --  Here we get the count.
    for i in l_opts_array.FIRST..l_opts_array.LAST loop
       if nvl(l_opts_array(i), '<NULL>') != '<NULL>' then
         number_of_arguments:=number_of_arguments+1;
       end if;
    end loop;
  end if;
  -- Create that job
  DBMS_SCHEDULER.CREATE_JOB(
    job_name=>jobname,
    job_type=> 'executable',
    job_action=> command,
    enabled=> FALSE,
    number_of_arguments=>number_of_arguments
  );
  -- Set the options argument, if opts was passed
  if nvl(opts, '<NULL>') != '<NULL>' then
    -- ASR 115302 - Scheduler is choking on multiple dash (-) args in
    --  single argument position - so split them into seperate args.
    for i in l_opts_array.FIRST..l_opts_array.LAST loop
       if nvl(l_opts_array(i), '<NULL>') != '<NULL>' then
          DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE (
            job_name          => jobname,
            argument_position => argument_position,
            argument_value    => '-'||ltrim(rtrim(l_opts_array(i)))
          );
          argument_position:= argument_position+1;
       end if;
    end loop;
  end if;
  -- Set the source path
  DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE (
      job_name          => jobname,
      argument_position => argument_position,
      argument_value    => source_path
    );
  argument_position:= argument_position+1;
  -- Set the target path
  DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE (
      job_name          => jobname,
      argument_position => argument_position,
      argument_value    => target_path
    );
  -- This caused the job to run
  DBMS_SCHEDULER.ENABLE(jobname);
  dbms_output.put_line('called job ');
  -- This will busy wait until job has completed
  err_msg:= get_completion_status(jobname);
end Convert_Multi_Sheet;

1 Ответ

0 голосов
/ 15 декабря 2018

Вы можете использовать команду EXEC для вызова процедуры в SQL * Plus, используя переменную связывания для OUT параметров.

VARIABLE v_err_msg varchar2
EXEC VMDB_OAS_doc_utils.Convert_Multi_Sheet (
      source_path =>  '/source/path/file.txt' 
      ,target_path =>  'target/path/filename.xls' --set it or let the 
                                                 --procedure set a path for you
      ,opts        =>  NULL
      ,err_msg     => :v_err_msg
   )
PRINT v_err_msg --prints the value returned from procedure.

Не ясно, что делает ваш sv2xls.pl, если target_path не предоставляется.По-видимому, он определен как IN OUT, что означает, что вы можете также передать назначенную переменную при вызове и получить (если) обновленное значение обратно из процедуры.

Теперь вы можете выполнять эти команды, используя SQL *Плюс по-разному, в зависимости от вашей операционной системы (Windows / Linux).См. это для Unix / Linux и это для Windows.

...