Bonjour à tous,
Je travaille sur une BD 11g Entreprise Edition sous Windows XP.
J'ai écrit un petit package dont le but est de supprimer des enregistrements dans une table :
J'ai créé un Program :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52 CREATE OR REPLACE PACKAGE Maint_pack AS PROCEDURE Spy(cTexte VARCHAR2); FUNCTION PurgeTable(cSchema VARCHAR2,cTable VARCHAR2,cChamp VARCHAR2,nNbJ NUMBER) RETURN NUMBER; END Maint_pack; / CREATE OR REPLACE PACKAGE BODY Maint_pack AS PROCEDURE Spy(cTexte VARCHAR2) IS cFileSpy VARCHAR2(100) :='Maint_pack_'||TO_CHAR(SYSDATE,'DD')||'.txt'; nFileSpy UTL_FILE.FILE_TYPE; cLineSpy VARCHAR2(400); BEGIN nFileSpy:=UTL_FILE.FOPEN('MAINT_DIR',cFileSpy,'A'); cLineSpy:='DATE : '||TO_CHAR(SYSDATE,'DD/MM/YY HH24:MI:SS')||' '||cTexte; UTL_FILE.PUT_LINE(nFileSpy,cLineSpy); UTL_FILE.FCLOSE(nFileSpy); END Spy; FUNCTION PurgeTable(cSchema VARCHAR2,cTable VARCHAR2,cChamp VARCHAR2,nNbJ NUMBER) RETURN NUMBER IS nPurgeTable NUMBER :=1; dFirstJour DATE; dLastJour DATE; cRequete VARCHAR2(5000); BEGIN cRequete:='SELECT MIN('||cChamp||') FROM '||cSchema||'.'||cTable; EXECUTE IMMEDIATE cRequete INTO dFirstJour; cRequete:='SELECT MAX('||cChamp||') FROM '||cSchema||'.'||cTable; EXECUTE IMMEDIATE cRequete INTO dLastJour; IF dLastJour - nNbJ > dFirstJour THEN dLastJour:=dLastJour-nNbJ; dFirstJour:=dFirstJour+15; IF dFirstJour < dLastJour THEN cRequete:='DELETE FROM '||cSchema||'.'||cTable||' WHERE '||cChamp||' < TO_DATE('||CHR(39)||dFirstJour||CHR(39)||')'; ELSE cRequete:='DELETE FROM '||cSchema||'.'||cTable||' WHERE '||cChamp||' < TO_DATE('||CHR(39)||dLastJour||CHR(39)||')'; END IF; Spy(cRequete); EXECUTE IMMEDIATE cRequete; COMMIT; END IF; RETURN nPurgeTable; EXCEPTION WHEN OTHERS THEN ROLLBACK; Spy(SQLERRM); nPurgeTable:=0; RETURN nPurgeTable; END PurgeTable; END Maint_pack; /
J'ai créé un Schedule :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49 BEGIN DBMS_SCHEDULER.CREATE_PROGRAM( program_name=>'PURGE_TABLE', program_action=>'TEST.Maint_pack.PurgeTable', program_type=>'STORED_PROCEDURE', number_of_arguments=>4, comments=>'Supprime les enregistrements dans une table.'); END; / BEGIN DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT( program_name=>'PURGE_TABLE', argument_position=>1, argument_name=>'SCH', argument_type=>'VARCHAR2', default_value=>'TEST'); END; / BEGIN DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT( program_name=>'PURGE_TABLE', argument_position=>2, argument_name=>'TAB', argument_type=>'VARCHAR2', default_value=>'DUAL'); END; / BEGIN DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT( program_name=>'PURGE_TABLE', argument_position=>3, argument_name=>'CHP', argument_type=>'VARCHAR2', default_value=>'JOUR'); END; / BEGIN DBMS_SCHEDULER.DEFINE_PROGRAM_ARGUMENT( program_name=>'PURGE_TABLE', argument_position=>4, argument_name=>'NBJ', argument_type=>'NUMBER', default_value=>90); END; / BEGIN DBMS_SCHEDULER.ENABLE('PURGE_TABLE'); END; /
J'ai créé un job :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 BEGIN DBMS_SCHEDULER.CREATE_SCHEDULE( schedule_name => 'DAILY_200000', start_date => systimestamp at time zone 'Europe/Paris', repeat_interval => 'FREQ=DAILY;BYHOUR=20;BYMINUTE=0;BYSECOND=0', comments => 'Tous les jours a 20h00.'); END; /
Le Job s'exécute bien mais j'ai, en retour, une erreur ORA-06576: ceci n'est pas un nom de fonction ou de procédure valide .
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39 BEGIN DBMS_SCHEDULER.CREATE_JOB( job_name => 'PURGE_LIGNE_CMD', program_name => 'PURGE_TABLE', schedule_name => 'DAILY_200000'); END; / BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE ( job_name => 'PURGE_LIGNE_CMD', argument_position => 1, argument_value => 'TEST'); END; / BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE ( job_name => 'PURGE_LIGNE_CMD', argument_position => 2, argument_value => 'LIGNE_CMD'); END; / BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE ( job_name => 'PURGE_LIGNE_CMD', argument_position => 3, argument_value => 'JOUR'); END; / BEGIN DBMS_SCHEDULER.SET_JOB_ARGUMENT_VALUE ( job_name => 'PURGE_LIGNE_CMD', argument_position => 4, argument_value => 90); END; / BEGIN DBMS_SCHEDULER.ENABLE('PURGE_LIGNE_CMD'); END; /
J'ai testé ma fonction sous SqlPlus :
Comment faire la même chose dans l'appel du PROGRAM ?
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 SQL> var myVar number; SQL> call Maint_pack.PurgeTable('TEST','QUANTITE','JOUR',90) into :myVar;
Est-ce une mauvaise technique ?
Faut-il faire cela autrement ?
Merci pour vos réponses.
Partager