Oracle 10g soumettre erreur de fonction d'emploi
-
28-09-2019 - |
Question
Je suis en train de planifier un travail dans Oracle 10g mais il dit:
ORA-01846:. Pas un jour valide de la semaine
Heres mon code:
declare
v_job_id1 number(19,0);
v_job_id2 number(19,0);
begin
dbms_job.submit(v_job_id1, 'CTX_DDL.OPTIMIZE_INDEX(''PSO_KEYWORD_SEARCH_IDX'', ''FULL'', 45);', NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24, NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7 );
commit;
end;
/
Mais ce travail comme prévu:
select NEXT_DAY(TRUNC(SYSDATE - 1), 4) + 13/24 from dual;
Des idées?
Merci!
Udo
La solution
Je ne peux pas expliquer pourquoi il arrive, mais Oracle accepte la syntaxe d'appel NEXT_DAY(...)
non valide en SQL.
Mais pas dans le code PL / SQL. Essayez ceci:
declare
d date;
begin
d := NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7;
end;
et vous avez parfaite erreur ORA-01846.
Oracle suggère solution avec commutation paramètre de session NLS_DATE_LANGUAGE avant d'appeler à NEXT_DAY « américain » et le retourner en arrière après le calcul.
Exemple:
DECLARE
FUNCTION get_next_day(dn IN VARCHAR2,ln IN VARCHAR2) RETURN DATE IS
CURSOR cr1 IS
SELECT value
FROM nls_session_parameters
WHERE parameter = 'NLS_DATE_LANGUAGE';
CURSOR cr2(dn1 IN VARCHAR2) IS
SELECT next_day(SYSDATE,UPPER(dn1))
FROM dual;
day DATE;
old_date_lang varchar2(128);
BEGIN
OPEN cr1;
FETCH cr1 INTO old_date_lang;
CLOSE cr1;
dbms_session.set_nls('NLS_DATE_LANGUAGE',ln);
OPEN cr2(dn);
FETCH cr2 INTO day;
CLOSE cr2;
dbms_session.set_nls('NLS_DATE_LANGUAGE', old_date_lang);
RETURN (day);
END;
BEGIN
dbms_output.put_line(TO_CHAR(get_next_day('MONDAY','AMERICAN'),'DAY dd/mm/yyyy'));
END;
De mon point de vue mieux éviter d'utiliser les fonctions de SNA-tout au courant, mais au jour de par semaine NLS-dépendu par définition: à quelques semaines des pays commence à partir de dimanche, dans d'autres pays - du lundi ...
Vous pouvez essayer d'utiliser la fonction TRUNC()
avec l'option 'D' pour réduire l'effet NLS:
select
NEXT_DAY(TRUNC(SYSDATE), 4) as D1,
NEXT_DAY(TRUNC(SYSDATE), 'THU') as D2,
case
-- next Thursday on this week
when (TRUNC(SYSDATE,'D') + 4) > trunc(sysdate) then (TRUNC(SYSDATE,'D') + 4)
-- next Thursday on next week
else (TRUNC(SYSDATE,'D') + 4) + 7
end as D3
from dual
Dans votre cas, cela ressemble à ce que:
dbms_job.submit(
JOB => v_job_id1,
WHAT => 'CTX_DDL.OPTIMIZE_INDEX(''PSO_KEYWORD_SEARCH_IDX'', ''FULL'', 45);',
NEXT_DATE => (
case
-- next Thursday on this week
when (TRUNC(SYSDATE,'D') + 4) > trunc(sysdate) then (TRUNC(SYSDATE,'D') + 4)
-- next Thursday on next week
else (TRUNC(SYSDATE,'D') + 4) + 7
end
),
INTERVAL => '
case
when (TRUNC(SYSDATE,''D'') + 4) > trunc(sysdate) then (TRUNC(SYSDATE,''D'') + 4)
else (TRUNC(SYSDATE,''D'') + 4) + 7
end
'
);
Mise à jour:
solution parfaite est d'obtenir le nom du jour de paramètres de SNA actuels et utiliser comme nom de jour. Parce que Aug-12-2010 certainement jeudi, vous pouvez l'utiliser comme date de base pour obtenir jour-of-the-semaine Nom:
select to_char(to_date('20100812','yyyymmdd'), 'DAY') from dual
Ensuite, ajouter le nom à l'appel de fonction au lieu de constante 4
:
dbms_job.submit(
JOB => v_job_id1,
WHAT => 'CTX_DDL.OPTIMIZE_INDEX(''PSO_KEYWORD_SEARCH_IDX'', ''FULL'', 45);',
NEXT_DATE => NEXT_DAY(TRUNC(SYSDATE), to_char(to_date('20100812','yyyymmdd'), 'DAY')) + 13/24,
INTERVAL => 'NEXT_DAY(TRUNC(SYSDATE), to_char(to_date(''20100812'',''yyyymmdd''), ''DAY'')) + 13/24 + 7'
);
Autres conseils
paramètre Intervalle doit être une chaîne avec l'expression SQL, exécutée par Oracle lors du calcul de la date et l'heure de la prochaine exécution.
Par conséquent, l'expression doit être cité:
dbms_job.submit(
JOB => v_job_id1,
WHAT => 'CTX_DDL.OPTIMIZE_INDEX(''PSO_KEYWORD_SEARCH_IDX'', ''FULL'', 45);',
NEXT_DATE => NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24,
INTERVAL => 'NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7'
);
Je souhaite publier cela comme une réponse au lieu d'un commentaire pour permettre un meilleur formatage du code. Commentaire de ThinkJet sur le paramètre d'intervalle est un argument valable, et je pense encore votre problème est lié à la « 4 » arg à NEXT_DAY - par exemple, ce code fonctionne:
SQL> declare
2 v_job_id1 number(19,0);
3 v_job_id2 number(19,0);
4 begin
5 dbms_job.submit(v_job_id1,
6 'begin null; end;',
7 NEXT_DAY(TRUNC(SYSDATE), 'Thursday') + 13/24,
8 'NEXT_DAY(TRUNC(SYSDATE), '||chr(39)||'Thursday'||chr(39)||') + 13/24 + 7' );
9 commit;
10 end;
11 /
PL/SQL procedure successfully completed.
Assurez-vous que vous utilisez le jour selon les paramètres locaux. Ex: - le jour « dimanche » devrait être écrit comme « Sonntag » en allemand. Je l'avais fait face à la question similaire ..: p