Я не могу объяснить, почему это происходит, но Oracle принимает неверный NEXT_DAY(...)
синтаксис вызова в простом SQL.
Но не в коде PL / SQL. Попробуйте это:
declare
d date;
begin
d := NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7;
end;
и вы получили совершенную ошибку ORA-01846.
Oracle предлагает обходной путь с переключением параметра сеанса NLS_DATE_LANGUAGE перед вызовом NEXT_DAY в 'AMERICAN' и возвратом его после расчета.
Пример:
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 и использовать его в качестве имени дня.
Поскольку 12 августа 2010 года, безусловно, четверг, вы можете использовать его в качестве базовой даты, чтобы получить название дня недели:
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'
);