Блок PLSQL для запуска задания с использованием dbms_scheduler для сбора статистики 30 схем

Я хочу создать один блок PL/SQL, в котором пытаюсь запустить задание с помощью пакета dbms_scheduler, и я хочу собрать статистику схемы по всем 30 схемам. Например:

begin
     dbms_scheduler_create_job(
     job_name => ....,
     job_type = > 'PL/SQL BLOCK',
     job_action => 'declare
      sch_lst dbms_stats.objecttab := dbms_stats.objecttab()
      begin
      sch_lst.extend(10);
      sch_lst(1).ownname := "ab";   --ab is the Schema name
      sch_lst(2).ownname := "cd";
      .........
      sch_lst(30).ownname := "xy";
      dbms_stats.gather_schema_stats( ......)
      end;
      /
      ',
     start_date => sysdate,
     ..........);
     end;
     /

person user8487380    schedule 04.12.2018    source источник
comment
sch_lst(1).ownname := "ab"; должно быть sch_lst(1).ownname := ''ab''; (две одинарные кавычки вместо одной двойной)   -  person a_horse_with_no_name    schedule 04.12.2018
comment
@a_horse_with_no_name будет ли он запущен или почему мы используем здесь ' ' вместо ".   -  person user8487380    schedule 04.12.2018


Ответы (2)


Перед start_date => sysdate, удалите /, а также в названии схемы вместо " (двойная кавычка) используйте '' (двойная одинарная кавычка), потому что она внутри оператор declare, который уже находится внутри одинарной кавычки.

begin
 dbms_scheduler_create_job(
 job_name => ....,
 job_type = > 'PL/SQL BLOCK',
 job_action => 'declare
  sch_lst dbms_stats.objecttab := dbms_stats.objecttab()
  begin
  sch_lst.extend(10);
  sch_lst(1).ownname := ''ab'';   --ab is the Schema name
  sch_lst(2).ownname := ''cd'';
  .........
  sch_lst(10).ownname := ''kl'';
  dbms_stats.gather_schema_stats( ......)
  end;
  ',
 start_date => sysdate,
 ..........);
 end;
 /

Затем после компиляции этого. вы можете проверить задание, используя execute dbms_schedule.run_job('<job_name>');

person Md Wasi    schedule 05.12.2018

Во-первых, вы можете создать такую ​​процедуру:

create or replace procedure pr_schema_stats is
  sch_lst owa.vc_arr;
begin
  sch_lst(1) := 'ab';
  sch_lst(2) := 'cd';  
  sch_lst(3) := 'ef';
  sch_lst(4) := 'gh';  
  sch_lst(5) := 'ij';
  sch_lst(6) := 'kl';  
  sch_lst(7) := 'mn';
  sch_lst(8) := 'op';  
  sch_lst(9) := 'rs';  
  sch_lst(10):= 'tu';  

 for i in 1..10
 loop    
   dbms_stats.gather_schema_stats(upper(sch_lst(i)),degree => 4, cascade => true );      
 end loop;
end; 

а затем вызовите из планировщика как:

declare
    v_job_name varchar2(70) := 'jb_gather_stats';
begin  
    dbms_scheduler.create_job(
        job_name => v_job_name,
        job_type => 'STORED_PROCEDURE',
        job_action => 'pr_schema_stats', 
        start_date => to_date('04-12-2018 19:00:00', 'dd-mm-yyyy hh24:mi:ss'),
        repeat_interval => 'FREQ=MONTHLY;INTERVAL=1;',
        auto_drop => false,
        comments => 'Produces statistics for Cost based SQL statements');

    dbms_scheduler.enable(v_job_name);    
end;

РЕДАКТИРОВАНИЕ: код процедуры можно заменить на :

create or replace procedure pr_schema_stats is   
begin

 for c in (   
           select u.username,
                 row_number() over (order by u.username) as rn
            from dba_users u
           where u.account_status = 'OPEN' 
             and u.username not like 'SYS%' 
           )
 loop
  begin
    dbms_stats.gather_schema_stats(c.username,degree => 4, cascade => true );      
   exception when others then 
    dbms_output.put_line(sqlerrm);
  end;
 end loop;
end;

чтобы включить все обычные схемы в задачу анализа.

person Barbaros Özhan    schedule 04.12.2018
comment
мы можем использовать ' ' вместо ". - person user8487380; 04.12.2018
comment
@user8487380 user8487380 да, если нужно использовать кавычки внутри кавычек, мы в основном используем '' (повторяющиеся одинарные кавычки для каждой одиночной кавычки внутри). Да, мы можем создать dbms_scheduler без хранимой процедуры, такой как PL/SQL BLOCK, как в вашем случае с этим форматом: PLSQL_BLOCK, но каждая двойная кавычка " должна быть заменена на '', я предпочитаю использовать STORED PROCEDURE. - person Barbaros Özhan; 04.12.2018
comment
даже имя схемы также использует '' или только'. - person user8487380; 04.12.2018
comment
@ user8487380 да, конечно, даже для имен схем используйте ''schema_name'' для случаев PLSQL_BLOCK, для которых аргумент job_action заключен в одинарные кавычки для всей строки. - person Barbaros Özhan; 04.12.2018
comment
Внутри объявления объявления означает, что job_action я использовал '' (двойная одинарная кавычка) вместо ", а снаружи я сохраняю ', поскольку это означает параметр start_date. Так это хорошо. - person user8487380; 05.12.2018
comment
Моя работа находится в состоянии scheduled, но я хочу изменить ее на состояние running. Как я могу сделать то же самое, что и выше. Пожалуйста, дай мне знать. - person user8487380; 05.12.2018
comment
@ user8487380 преобразовать аргумент start_date в подходящее значение, такое как значение с текущим днем ​​​​и часом в ближайшем будущем, а затем вам нужно включить его с помощью dbms_scheduler.enable('jb_gather_stats'), всякий раз, когда достигается определенное время, он должен работать, а состояние running сохраняется в зависимости от вашей работы. продолжительность. - person Barbaros Özhan; 05.12.2018
comment
После запуска приведенного выше оператора были проанализированы только несколько схем, а не все. Как решить эту проблему, чтобы была проанализирована вся пользовательская схема. Помогите мне, пожалуйста. - person user8487380; 10.12.2018
comment
@user8487380 user8487380 К сожалению, я не знаю. - person Barbaros Özhan; 10.12.2018
comment
@user8487380 user8487380 вы можете добавить exception handling для такой ситуации (чтобы пропустить проблемный шаг). - person Barbaros Özhan; 18.12.2018
comment
но это хорошая практика, я использую 1 begin .. end; для каждой схемы. Если какой-либо из них выйдет из строя, остальная часть схемы соберет статистику. внутри каждого begin .. end; я использую exception handling. Это означает, что для схемы 10 используйте 10 begin .. end; и 10 "обработку исключений". Это правильно? - person user8487380; 18.12.2018
comment
@user8487380 user8487380 Я думаю, что это будет беспорядок в коде. В моем случае, если процесс завершается сбоем для любой из схем, уже выполняется итерация к следующей. - person Barbaros Özhan; 18.12.2018
comment
@ user8487380 точно, да. Учтите следующее: begin for c in ( select level lvl from dual connect by level <= 10 ) loop begin dbms_output.put_line(c.lvl / (c.lvl - 5)); exception when others then dbms_output.put_line(sqlerrm); end; end loop; end; вызывает исключение в 5-й строке, но после этого выполняет итерацию. - person Barbaros Özhan; 18.12.2018
comment
@user8487380 user8487380 да, конечно можно. - person Barbaros Özhan; 18.12.2018
comment
For i in 1 .. lvl.count(20) loop показывает какую-то ошибку. Я хочу выбрать только 20 итераций в первый раз и следующие 20 итераций в следующий раз для другой операции. Как использовать 1-ю схему 20 в итерации. - person user8487380; 18.12.2018
comment
@ user8487380 ничего, кроме замены 10 на 20 в connect by level <= 10 - person Barbaros Özhan; 18.12.2018
comment
но здесь я использую объявление переменной PL/SQL, означающее a_arr как VARRAY. Бывший type a_arr is varray(30) of varchar2(20). Эту переменную я использую внутри For loop как for i in 1 .. a_arr.count(20) вот так в 1-й раз, а затем во 2-й раз for i in a_arr.count(21).. a_arr.count. В то же время я получаю ошибку. как решить эту проблему. - person user8487380; 18.12.2018
comment
Давайте продолжим обсуждение в чате. - person Barbaros Özhan; 18.12.2018