1

Oracle 10gでジョブをスケジュールしようとしていますが、次のように表示されます。

ORA-01846:有効な曜日ではありません。

これが私のコードです:

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

しかし、これは意図したとおりに機能します。

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

何か案は?

ありがとうございました!

宇土

4

4 に答える 4

2

間隔パラメーターは、次回の実行の日時を計算するときに Oracle によって実行される SQL 式を含む文字列である必要があります。

したがって、式を引用する必要があります。

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'
);
于 2010-08-12T12:11:48.427 に答える
1

より良いコードフォーマットを可能にするために、コメントではなく回答としてこれを投稿しています。間隔パラメーターに関するThinkJetのコメントは有効なポイントですが、問題はNEXT_DAYの「4」引数に関連していると思います。たとえば、このコードは機能します。

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.
于 2010-08-12T13:23:49.043 に答える
1

なぜそうなるのかは説明できませんが、Oracle はNEXT_DAY(...)プレーン SQL で無効な呼び出し構文を受け入れます。

ただし、PL/SQL コードではありません。これを試して:

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

完璧なORA-01846エラーが発生しました。

Oracle は、NEXT_DAY を 'AMERICAN' に呼び出す前に NLS_DATE_LANGUAGE セッション パラメータを切り替え、計算後に戻すという回避策を提案しています。

例:

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;

私の観点からは、NLS 対応関数をまったく使用しない方がよいのですが、定義上、曜日は NLS に依存しています。一部の国では、週は日曜日から始まり、他の国では月曜日から始まります...

TRUNC()「D」オプションを指定して関数を使用して、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

あなたの場合、これは次のようになります。

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

アップデート:

完全な回避策は、現在の NLS 設定から曜日名を取得し、曜日名として使用することです。2010 年 8 月 12 日は間違いなく木曜日なので、曜日名を取得する基準日として使用できます。

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

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'
);
于 2010-08-12T13:35:05.293 に答える
1

ロケールに従って日を使用していることを確認してください。例: - 「日曜日」という日は、ドイツ語で「Sonntag」と書く必要があります。私は同様の問題に直面していました.. :p

于 2011-12-12T11:07:26.537 に答える