2010-08-12 5 views
1

Je suis en train de planifier un travail dans Oracle 10g mais il dit:oracle 10g soumettre erreur de fonction d'emploi

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

+0

Je n'ai jamais vu un nombre utilisé comme deuxième argument à NEXT_DAY, bien que comme vous l'avez indiqué, il fonctionne dans une instruction SELECT. Aviez-vous l'intention de vouloir dire jeudi? Que se passe-t-il si vous utilisez la chaîne "Thursday" au lieu de 4? – dpbradley

+0

@dpbradley: Cela fonctionne dans une phrase autonome. Je ne peux pas utiliser de littéraux depuis que je suis en Espagne et 'DAY' dépend du NLS. Donc, si le paramètre nls est différent dans la production de dev je pourrais avoir des problèmes. Mais 4 devrait fonctionner indépendamment de la NLS. – ssedano

Répondre

1

Je ne peux pas expliquer pourquoi il arrive , mais Oracle accepte la syntaxe d'appel NEXT_DAY(...) non valide en langage 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 une erreur ORA-01846 parfaite.

Oracle suggère une solution de contournement avec la commutation du paramètre de session NLS_DATE_LANGUAGE avant d'appeler NEXT_DAY à 'AMERICAN' et de le renvoyer 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 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 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 NLS 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 

Puis ajouter le nom à l'appel de fonction au lieu de 4 constante:

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' 
); 
+0

@ThinkJet: cela dépendrait toujours de nls. N'y a-t-il pas un moyen de définir un travail à exécuter tous les jeudis à une heure donnée (c'est-à-dire 13 heures)? Merci – ssedano

+2

@ThinkJet - Je pense que la différence entre l'appel de SQL et PL/SQL est qu'avec PL/SQL vous utilisez les paramètres NLS de la base de données au lieu des paramètres du client. – dpbradley

+0

Réponse mise à jour. J'espère que c'est une solution indépendante NLS ... – ThinkJet

2

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 course.

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' 
); 
+0

Il ne cesse de dire que ce n'est pas un jour valable. Merci quand même. – ssedano

1

Je poste ceci comme une réponse au lieu d'un commentaire pour permettre une meilleure mise en forme de code. Commentaire de ThinkJet sur le paramètre d'intervalle est un argument valable, et je pense encore votre problème est lié à la arg « 4 » à 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. 
+0

@dpbradley: Merci mais j'ai besoin d'être indépendant. – ssedano

1

Assurez-vous que vous utilisez le jour en fonction des paramètres régionaux. Pour Ex: - le jour «Dimanche» doit être écrit en tant que «Sonntag» en allemand. J'avais rencontré le même problème ..: p