Domanda

Sto cercando di pianificare un processo in Oracle 10g, ma si dice:

ORA-01846:. Non un giorno valido della settimana

Ecco il mio codice:

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;
/

Ma questo lavoro come previsto:

select NEXT_DAY(TRUNC(SYSDATE - 1), 4) + 13/24 from dual;

tutte le idee?

Grazie!

Udo

È stato utile?

Soluzione

Non può spiegare perché succede, ma Oracle accetta sintassi di chiamata NEXT_DAY(...) non valida in SQL pianura.

codice

Ma non in PL / SQL. Prova questo:

declare 
  d date;
begin
  d := NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7;
end;

e hai ottenuto perfetto errore ORA-01846.

Oracle suggerisce soluzione con commutazione parametro di sessione NLS_DATE_LANGUAGE prima di chiamare NEXT_DAY a 'americano' e tornare indietro dopo il calcolo.

Esempio:

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;

Dal mio punto di vista meglio evitare di utilizzare le funzioni di NLS di riconoscere a tutti, ma il giorno-di-un-settimana-NLS dipendeva per definizione: in alcuni paesi settimana parte da Domenica, in altri paesi - dal Lunedi ...

Si può provare a utilizzare la funzione TRUNC() opzione 'D' con effetto di abbassare 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

Nel tuo caso questo sembra che:

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

Aggiornamento:

Perfect soluzione è quella di ottenere il nome del giorno da impostazioni NLS correnti e uso come nome del giorno. Perché Ago-12-2010 sicuramente Giovedi è possibile utilizzarlo come data di base per ottenere il giorno-of-the-settimana Nome:

select to_char(to_date('20100812','yyyymmdd'), 'DAY') from dual  

Quindi aggiungere un nome alla funzione di chiamata al posto di costante 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'
);

Altri suggerimenti

parametro Interval deve essere una stringa con l'espressione SQL, eseguito da Oracle per il calcolo data e l'ora della successiva esecuzione.

Quindi espressione deve essere citato:

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

sto postando questo come una risposta, invece di un commento per permettere la formattazione codice migliore. Il commento di ThinkJet sul parametro intervallo è un valido punto, e io continuo a pensare che il problema è legato alla '4' arg per NEXT_DAY - per esempio, questo codice funziona:

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.

Assicurarsi che si sta utilizzando il giorno secondo il locale. Per Es: - il giorno 'Domenica' dovrebbe essere scritto come 'Sonntag' in tedesco. Avevo affrontato il problema simile ..: p

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top