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

Était-ce utile?

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

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top