Oracle 10G Enviar erro da função do trabalho
-
28-09-2019 - |
Pergunta
Estou tentando agendar um emprego no Oracle 10G, mas diz:
ORA-01846: Não é um dia válido da semana.
Aqui está meu código:
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;
/
Mas este trabalho como pretendido:
select NEXT_DAY(TRUNC(SYSDATE - 1), 4) + 13/24 from dual;
Alguma ideia?
Obrigada!
Udo
Solução
Não posso explicar por que isso acontece, mas o Oracle aceita inválido NEXT_DAY(...)
Ligue para a sintaxe na simples SQL.
Mas não no código PL/SQL. Experimente isso:
declare
d date;
begin
d := NEXT_DAY(TRUNC(SYSDATE), 4) + 13/24 + 7;
end;
E você recebeu um erro perfeito do ORA-01846.
O Oracle sugere uma solução alternativa com o parâmetro NLS_DATE_LANGAGE Antes de ligar para 'American' e devolvê -lo após o cálculo.
Exemplo:
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;
Do meu ponto de vista, melhor para evitar o uso de funções com reconhecimento de NLS, mas dependente do NLS dependente do dia da semana: em alguns países, a semana começa a partir de domingo, em outros países-a partir de segunda-feira ...
Você pode tentar usar TRUNC()
Função com a opção 'D' para reduzir o efeito do 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
No seu caso, isso se parece com isso:
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
'
);
Atualizar:
A solução alternativa perfeita é obter o nome do dia das configurações atuais do NLS e usar como nome do dia. Porque, 12-2010 de agosto, definitivamente quinta-feira, você pode usá-lo como data base para obter o nome do dia da semana:
select to_char(to_date('20100812','yyyymmdd'), 'DAY') from dual
Em seguida, adicione o nome à chamada de função em vez 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'
);
Outras dicas
O parâmetro de intervalo deve ser uma string com expressão SQL, executada pelo Oracle ao calcular a data e a hora da próxima execução.
Portanto, a expressão deve ser citada:
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'
);
Estou postando isso como uma resposta em vez de um comentário para permitir uma melhor formatação de código. O comentário do ThinkJet sobre o parâmetro de intervalo é um ponto válido, e ainda acho que seu problema está relacionado ao '4' arg para o próximo dia - por exemplo, esse código funciona:
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.
Certifique -se de estar usando o dia de acordo com o local. Para Ex:- O dia 'Domingo' deve ser escrito como 'Sonntag' em alemão. Eu tinha enfrentado o problema semelhante ..: p