Oracle PL/SQL Tutorial/System Packages/DBMS JOB — различия между версиями
Admin (обсуждение | вклад) м (1 версия) |
|
(нет различий)
|
Текущая версия на 10:05, 26 мая 2010
Содержание
DBMS_JOB demonstration
SQL>
SQL> CREATE TABLE run_table (message VARCHAR2(40));
Table created.
SQL>
SQL> -- create a procedure to insert rows into the test table:
SQL> CREATE OR REPLACE PROCEDURE p_run_insert IS
2 BEGIN
3 INSERT INTO run_table VALUES ("Execution at " || to_char(sysdate, "dd-mon-yy hh:mi:ss") ) ;
4 COMMIT ;
5 END;
6 /
Procedure created.
SQL>
SQL> -- schedule that procedure to run every 10 seconds (approximately):
SQL> VARIABLE p_jobno number
SQL> BEGIN
2 DBMS_JOB.SUBMIT (:p_jobno,"P_RUN_INSERT;", SYSDATE, "SYSDATE + (10/(24*60*60))");
3 COMMIT; /* must commit after SUBMIT */
4 END;
5 /
PL/SQL procedure successfully completed.
SQL> PRINT p_jobno
P_JOBNO
----------
122
SQL>
SQL>
SQL> exec dbms_job.remove(1)
BEGIN dbms_job.remove(1); END;
*
ERROR at line 1:
ORA-23421: job number 1 is not a job in the job queue
ORA-06512: at "SYS.DBMS_SYS_ERROR", line 86
ORA-06512: at "SYS.DBMS_IJOB", line 529
ORA-06512: at "SYS.DBMS_JOB", line 171
ORA-06512: at line 1
SQL>
SQL> drop table run_table;
Table dropped.
SQL>
SQL>
DBMS_JOB.SUBMIT
SQL>
SQL>
SQL> DECLARE
2 lv_job_num NUMBER;
3 BEGIN
4 DBMS_JOB.SUBMIT(lv_job_num, "LOG_SOURCE;", SYSDATE, "SYSDATE + 1/24", NULL);
5 DBMS_OUTPUT.PUT_LINE("Assigned Job #: " || lv_job_num);
6 END;
7 /
PL/SQL procedure successfully completed.
SQL>
Job number
SQL>
SQL>
SQL> set echo on
SQL>
SQL> create table t ( msg varchar2(80) );
Table created.
SQL>
SQL> create or replace procedure p( p_job in number, p_next_date in OUT date ) as
2 l_next_date date default p_next_date;
3 begin
4 p_next_date := trunc(sysdate)+1+3/24;
5 insert into t values ( "Next date was "" || to_char(l_next_date,"dd-mon-yyyy hh24:mi:ss") ||
6 "" Next date IS " || to_char(p_next_date,"dd-mon-yyyy hh24:mi:ss") );
7 end;
8 /
Procedure created.
SQL>
SQL> variable n number
SQL>
SQL> exec dbms_job.submit( :n, "p(JOB,NEXT_DATE);" );
PL/SQL procedure successfully completed.
SQL>
SQL> select what, interval,
2 to_char(last_date,"dd-mon-yyyy hh24:mi:ss") last_date,
3 to_char(next_date,"dd-mon-yyyy hh24:mi:ss") next_date
4 from user_jobs
5 where job = :n
6 /
WHAT
--------------------------------------------------------------------------------
INTERVAL
--------------------------------------------------------------------------------
LAST_DATE NEXT_DATE
-------------------- --------------------
p(JOB,NEXT_DATE);
null
25-jul-2008 19:22:27
SQL>
SQL> exec dbms_job.run( :n );
PL/SQL procedure successfully completed.
SQL>
SQL> select * from t;
MSG
--------------------------------------------------------------------------------
Next date was "" Next date IS 26-jul-2008 03:00:00
SQL>
SQL> select what, interval,
2 to_char(last_date,"dd-mon-yyyy hh24:mi:ss") last_date,
3 to_char(next_date,"dd-mon-yyyy hh24:mi:ss") next_date
4 from user_jobs
5 where job = :n
6 /
WHAT
--------------------------------------------------------------------------------
INTERVAL
--------------------------------------------------------------------------------
LAST_DATE NEXT_DATE
-------------------- --------------------
p(JOB,NEXT_DATE);
null
25-jul-2008 19:22:27 26-jul-2008 03:00:00
SQL>
SQL> exec dbms_job.remove( :n );
PL/SQL procedure successfully completed.
SQL> drop table t;
Table dropped.
SQL>
Schedule the procedure to run now and every night at 3 AM:
SQL>
SQL>
SQL> create table my_stats_table
2 (object_name varchar2(30),
3 gather_date date default sysdate);
SQL>
SQL>
SQL> create or replace procedure gather_my_stats as
2 olist dbms_stats.objectTab;
3 begin
4 dbms_stats.gather_schema_stats(user,
5 cascade=>TRUE,
6 method_opt=> "AUTO",
7 options=>"GATHER AUTO",
8 objlist=>olist);
9
10 if olist.COUNT > 0 then
11 FOR x in 1..olist.COUNT LOOP
12 insert into my_stats_table (object_name)
13 values(olist(x).objname);
14 END LOOP;
15 end if;
16 end;
17 /
Procedure created.
SQL>
SQL> variable job_no number
SQL>
SQL> exec dbms_job.submit(:job_no, "GATHER_MY_STATS;", SYSDATE, "TRUNC(SYSDATE+1) + 3/24")
PL/SQL procedure successfully completed.
SQL>
SQL> commit;
Commit complete.
SQL>
SQL> print job_no
JOB_NO
----------
141
SQL>
SQL>
SQL> drop table my_stats_table;
Table dropped.
SQL>
SQL>
SQL>
Submit a job and query the user_jobs
SQL>
SQL> create or replace procedure analyze_my_tables
2 as
3 begin
4 for x in ( select table_name from user_tables )
5 loop
6 execute immediate
7 "analyze table " || x.table_name || " compute statistics";
8 end loop;
9 end;
10 /
Procedure created.
SQL>
SQL> declare
2 l_job number;
3 begin
4 dbms_job.submit( job => l_job,
5 what => "analyze_my_tables;",
6 next_date => trunc(sysdate)+1+3/24,
7 interval => "trunc(sysdate)+1+3/24" );
8 end;
9 /
PL/SQL procedure successfully completed.
SQL>
SQL> select job, to_char(sysdate,"dd-mon"),
2 to_char(next_date,"dd-mon-yyyy hh24:mi:ss"),
3 interval, what
4 from user_jobs
5 /
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
21 25-jul 01-jan-4000 00:00:00
SYSDATE + (10/(24*60*60))
P_RUN_INSERT;
22 25-jul 01-jan-4000 00:00:00
SYSDATE + (10/(24*60*60))
P_RUN_INSERT;
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
41 25-jul 26-jul-2008 03:00:00
TRUNC(SYSDATE+1) + 3/24
GATHER_MY_STATS;
61 25-jul 25-jul-2008 19:34:32
SYSDATE + 1/24
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
LOG_SOURCE;
101 25-jul 01-jan-4000 00:00:00
SYSDATE + (10/(24*60*60))
P_RUN_INSERT;
82 25-jul 26-jul-2008 03:00:00
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
trunc(sysdate)+1+3/24
analyze_my_tables;
121 25-jul 01-jan-4000 00:00:00
SYSDATE + (10/(24*60*60))
P_RUN_INSERT;
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
122 25-jul 01-jan-4000 00:00:00
SYSDATE + (10/(24*60*60))
P_RUN_INSERT;
141 25-jul 25-jul-2008 21:18:41
TRUNC(SYSDATE+1) + 3/24
GATHER_MY_STATS;
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
161 25-jul 25-jul-2008 19:46:13
SYSDATE + 1/24
LOG_SOURCE;
162 25-jul 25-jul-2008 19:49:44
SYSDATE + 1/24
JOB TO_CHA TO_CHAR(NEXT_DATE,"D
---------- ------ --------------------
INTERVAL
--------------------------------------------------------------------------------
WHAT
--------------------------------------------------------------------------------
LOG_SOURCE;
182 25-jul 26-jul-2008 03:00:00
trunc(sysdate)+1+3/24
analyze_my_tables;
12 rows selected.
Submit a job and run
SQL>
SQL> set echo on
SQL>
SQL> create table t ( msg varchar2(20), cnt int );
Table created.
SQL>
SQL> insert into t select "from SQL*PLUS", count(*) from session_roles;
1 row created.
SQL>
SQL> variable n number
SQL>
SQL> exec dbms_job.submit(:n,"insert into t select ""from job"", count(*) from session_roles;");
PL/SQL procedure successfully completed.
SQL>
SQL> print n
N
----------
181
SQL>
SQL> exec dbms_job.run(:n);
PL/SQL procedure successfully completed.
SQL>
SQL> select * from t;
MSG CNT
-------------------- ----------
from SQL*PLUS 12
from job 0
SQL> drop table t;
Table dropped.
SQL>
Submit job to change password
SQL> CREATE TABLE EMP(
2 EMPNO NUMBER(4) NOT NULL,
3 ENAME VARCHAR2(10),
4 JOB VARCHAR2(9),
5 MGR NUMBER(4),
6 HIREDATE DATE,
7 SAL NUMBER(7, 2),
8 COMM NUMBER(7, 2),
9 DEPTNO NUMBER(2)
10 );
Table created.
SQL> INSERT INTO EMP VALUES(2, "Jack", "Tester", 6,TO_DATE("20-FEB-1981", "DD-MON-YYYY"), 1600, 300, 30);
1 row created.
SQL> INSERT INTO EMP VALUES(3, "Wil", "Tester", 6,TO_DATE("22-FEB-1981", "DD-MON-YYYY"), 1250, 500, 30);
1 row created.
SQL> INSERT INTO EMP VALUES(4, "Jane", "Designer", 9,TO_DATE("2-APR-1981", "DD-MON-YYYY"), 2975, NULL, 20);
1 row created.
SQL> INSERT INTO EMP VALUES(5, "Mary", "Tester", 6,TO_DATE("28-SEP-1981", "DD-MON-YYYY"), 1250, 1400, 30);
1 row created.
SQL> INSERT INTO EMP VALUES(6, "Black", "Designer", 9,TO_DATE("1-MAY-1981", "DD-MON-YYYY"), 2850, NULL, 30);
1 row created.
SQL> INSERT INTO EMP VALUES(7, "Chris", "Designer", 9,TO_DATE("9-JUN-1981", "DD-MON-YYYY"), 2450, NULL, 10);
1 row created.
SQL> INSERT INTO EMP VALUES(8, "Smart", "Helper", 4,TO_DATE("09-DEC-1982", "DD-MON-YYYY"), 3000, NULL, 20);
1 row created.
SQL> INSERT INTO EMP VALUES(9, "Peter", "Manager", NULL,TO_DATE("17-NOV-1981", "DD-MON-YYYY"), 5000, NULL, 10);
1 row created.
SQL> INSERT INTO EMP VALUES(10, "Take", "Tester", 6,TO_DATE("8-SEP-1981", "DD-MON-YYYY"), 1500, 0, 30);
1 row created.
SQL> INSERT INTO EMP VALUES(13, "Fake", "Helper", 4,TO_DATE("3-DEC-1981", "DD-MON-YYYY"), 3000, NULL, 20);
1 row created.
SQL>
SQL> create table PASSWORD_AUDIT (empno number,date_change date );
SQL>
SQL> create or replace procedure admin.reset_password(id varchar2) is
2 v_username varchar2(30);
3 v_job number;
4 begin
5 select ename into v_username from emp where empno = id and mgr = ( select empno from emp where ename = user );
6 insert into password_audit values (id, user, sysdate);
7 dbms_job.submit(v_job,"begin execute immediate " ||"""alter user ""||v_username||"" "||" identified by "||v_username||"""; end;");
8 exception
9 when no_data_found then
10 raise_application_error(-20000, "You are not authorised to alter emp "||id);
11 end;
12 /
SQL> drop table emp;
Table dropped.
Use dbms_job.submit to call "execute immediate"
SQL> create table myTable (
2 tname varchar2(30),
3 cname varchar2(30),
4 changed date
5 );
Table created.
SQL>
SQL> create or replace procedure RUN_DDL(m varchar2) is
2 pragma autonomous_transaction;
3 begin
4 execute immediate m;
5 end;
6 /
SQL>
SQL> create or replace procedure ADD_COLUMN(p_table varchar2, p_column varchar2) is
2 v number;
3 j number;
4 begin
5 insert into myTable values (p_table, p_column, sysdate);
6 dbms_job.submit(j, "run_ddl(""alter table "||p_table||" add "||p_column||""");");
7 end;
8 /
Procedure created.
SQL>
SQL>
SQL> drop table myTable;
Table dropped.