2010-08-12 2 views
1

를 제출하지만 말한다 :오라클 10g는 내가 오라클 10g의 작업을 예약하기 위해 노력하고있어 직무 오류

ORA-01846 : 일주일의 유효한 일.

은 Heres는 내 코드 :

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; 

어떤 아이디어?

감사합니다.

우도

+0

NEXT_DAY의 두 번째 인수로 사용 된 번호를 본 적이 없습니다. SELECT 문에서 작동한다고 표시 했으므로. 목요일을 뜻하는거야? 4 대신에 "목요일"이라는 문자열을 사용하면 어떻게됩니까? – dpbradley

+0

@ dpbradley : 독립 실행 형 문장으로 작동합니다. 내가 스페인에있을 때부터 리터럴을 사용할 수 없으며 'DAY'는 nls에 달려있다. 그래서 nls 매개 변수가 dev에서 프로덕션에서 다른 경우 문제가있을 수 있습니다. 그러나 4는 nls에 관계없이 작동해야합니다. – ssedano

답변

1

, 오라클은 일반 SQL에서 유효하지 않은 NEXT_DAY(...) 호출 구문을 허용합니다.

그러나 PL/SQL 코드에는 없습니다. 이것을 시도하십시오 :

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

그리고 완벽한 ORA-01846 오류가 발생했습니다.

오라클은 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-의존하기 : 일부 국가에서 주 일요일부터 시작 이처럼 보이는 귀하의 경우에는

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 

: - 기타 국가에서

... 월요일부터 당신은 NLS 효과를 낮추기 위해 'D'옵션 TRUNC() 기능을 사용하려고 할 수 있습니다 그 :

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 설정에서 하루의 이름을 얻을 일 이름으로 사용하는 것입니다.8월이-12-2010 확실히 목요일 당신이 얻을 기준일로 사용할 수 있습니다 때문에 일 - 중 - 주 이름 :

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

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

그럼 대신 4 상수의 함수 호출에 이름을 추가

+0

@ThinkJet : 이것은 여전히 ​​nls 의존적입니다. 주어진 시간 (예 : 오후 1시)에 매주 목요일에 일자리를 구할 수있는 방법이 있습니까? 감사합니다. – ssedano

+2

@ThinkJet - SQL과 PL/SQL의 호출을 실행하는 것의 차이점은 PL/SQL에서 클라이언트 설정 대신 데이터베이스의 NLS 매개 변수를 사용한다는 것입니다. – dpbradley

+0

답변이 업데이트되었습니다. 나는 그것이 NLS 독립적 인 솔루션이기를 희망한다 ... – ThinkJet

2

간격 매개 변수는 다음 실행의 날짜와 시간을 계산할 때 오라클에 의해 실행 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' 
); 
+0

그것은 말하고있다 유효한 일 thou가 아니다. 어쨌든 고맙습니다. – ssedano

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. 
가 발생하는 이유를 설명 할 수
+0

@ dpbradley : 고맙지 만 NLS와 독립적이어야합니다. – ssedano

1

로케일에 따라 요일을 사용하고 있는지 확인하십시오. 예 : 일요일 '일요일'은 독일어로 'Sonntag'로 작성해야합니다. 비슷한 문제가 발생했습니다. :