2012-12-10 4 views
4

ALL_ARGUMENTS를 사용하여 oracle 10g에서 인수 목록을 가져 오지만 인수의 기본값이 있는지 확인할 수 없습니다. 내가 할 수 있니?기본값으로 인수 목록 가져 오기

+0

'ALL_ARGUMENTS'의'DEFAULT_VALUE' 칼럼 이외의 것을 찾으십니까? (성가 시게,'LONG'은 약간의 고통으로 작용할 것입니다)? 해당 열의 데이터를 해석하는 데 문제가 있습니까? –

+1

@ user1662382 : default_value 열은 [link] 문서 (http://docs.oracle.com/cd/B28359_01/server.111/b28320/statviews_1014.htm)에서 언급 한 것처럼 나중에 사용하도록 예약되어 있다고 생각합니다. 또한 아직 해결되지 않은 버그 # 393152가 있습니다. –

+0

11g에서는 [all_arguments]의 [defaulted] 열에 인수가 기본값을 가진 경우 표시됩니다. 이 열은 10g에 없으며 다른 간단한 방법을 찾으려고합니다. – Alexander

답변

0

아래의 코드 샘플에서는 10g에서 plsql 프로그래밍을 사용해야 할 수도 있습니다. 이 솔루션은 기본적으로 매우 낮은 수준의 프리미티브를 사용하여 함수/프로 시저 선언 파서의 일부분을 작성하기 때문에 어떤 의미에서 확실히 무차별 적입니다. 그러나, 정규 표현식 기능 ... 중 10g에

를 사용할 수없는 코드의 요지는 다음과 같습니다 절차/함수 선언의 소스 코드 라인

  • 노트 이름의 이상

    • 으로 반복 가장 최근에 선언 된 루틴
    • 은 'DEFAULT'키워드를 포함하는 모든 행을 분석하여 인수 이름과 기본값을 얻습니다 (코드 샘플에서 자세히 설명하지 않음). 함정의

    주의 :

    • 여러 선언 문자열을 열어 C 스타일의 주석을 포함
    • C 스타일의 코멘트 (라/* ㅋ ㅋ ㅋ ㅋ/ ㅋ ㅋ ㅋ ㅋ * * /)
    • 키워드가 포함 된 문자열 리터럴

    어쨌든 도움이되는 희망, 최고의 안부.

    코드 :

    DECLARE 
        l_arg_and_more VARCHAR2(400); 
        l_current_unit VARCHAR2(400); 
        l_default_spec VARCHAR2(400); 
        l_offset_default BINARY_INTEGER; 
        l_offset_eoname BINARY_INTEGER; 
    BEGIN 
        FOR i IN (
         select text 
         from all_source 
         where owner = '<name of owner>' 
          and name = '<object name>' 
          and type in ('PACKAGE', 'PROCEDURE', 'FUNCTION') 
          and text not like '--%' 
        order by line 
        ) LOOP 
         IF i.text LIKE '%FUNCTION%' OR i.text LIKE '%PROCEDURE%' THEN 
         IF i.text LIKE '%FUNCTION%' THEN 
          l_current_unit := LTRIM(SUBSTR(i.text, INSTR(i.text, 'FUNCTION') + LENGTH('FUNCTION')), ' '); 
          l_offset_eoname := INSTR(l_current_unit, ' ');    
          IF l_offset_eoname = 0 OR l_offset_eoname > INSTR(l_current_unit, '(') THEN 
           l_offset_eoname := INSTR(l_current_unit, '('); 
          END IF; 
          IF l_offset_eoname <> 0 THEN 
           l_current_unit := SUBSTR(l_current_unit, 1, l_offset_eoname-1); 
          ELSE 
           l_current_unit := 'unidentified'; 
          END IF; 
         END IF; 
         END IF; 
         -- 
         IF i.text LIKE '%DEFAULT%' THEN 
         l_offset_default := INSTR (i.text, 'DEFAULT'); 
         l_arg_and_more := SUBSTR(i.text, 1, l_offset_default - 1); 
         l_default_spec := SUBSTR(i.text, l_offset_default + LENGTH('DEFAULT') + 1); 
         -- 
         -- process l_arg_and_more to get the arg name, l_default_spec for the default value 
         -- 
         END IF; 
        END LOOP;    
    END; 
    
  • 0

    나는 그것이 조금 너무 늦은 알고 있지만이 도움이 될 수 있습니다. 나는이 시점에서 비슷한 문제에 직면하고있다. 이 DEFAULT_VALUE라는 이름의 열이지만, 심지어는 11g에 유형은 LONG하고 해결하려면 CLOB로 변환하는 두통의 ...보기 SYS.ALL_ARGUMENTS에서

    SELECT SUBSTR(final_str, start_pos+1, (end_pos-start_pos-1)) dflt_values, start_pos, end_pos 
    FROM 
    (
        SELECT start_pos, final_end_pos end_pos, MOD(ROWNUM, 2) rno, final_str FROM 
        (
        SELECT distinct start_pos, end_pos, final_str, (CASE WHEN end_pos < start_pos THEN (start_pos*2) ELSE end_pos END) final_end_pos 
        FROM 
        (
        SELECT Instr(final_str, '=', LEVEL) start_pos, Instr(final_str, ',', LEVEL) end_pos, final_str --<<-- distinct 
         FROM 
        (
        SELECT RTRIM(SUBSTR(str, 1, e_start), ',')||RTRIM(SUBSTR(str, e_start, e_end-e_start), ')') final_str 
        , e_start 
        , e_end 
    , e_end-e_start 
         FROM 
        (
        SELECT str, Instr(str, ',', 1, 5) e_start, Instr(str, ')') e_end 
         FROM 
        (
        SELECT REPLACE(REPLACE(REPLACE(SUBSTR(str, INSTR(str, '(')+1), chr(32), ''), chr(10), chr(32)), 'DEFAULT', ':=') str 
         FROM 
        (
        SELECT 'PROCEDURE Some_Proc(p_arg1 VARCHAR2:= ''Arg1'' 
             , p_arg2 VARCHAR2:= ''Arg2'' 
             , p_arg3 DATE  DEFAULT ''SYSDATE-90''                     
             , p_arg4 VARCHAR2 DEFAULT ''NULL''           
             , p_arg5 NUMBER := ''10'')' str 
         FROM dual 
        )))) 
        CONNECT BY LEVEL <= LENGTH(final_str) 
        ) 
        WHERE start_pos > 0 
        ORDER BY start_pos, end_pos 
    )) 
    WHERE rno > 0 
    /
    
    0

    을 더 많은 테스트가 필요합니다.

    가장 쉬운 방법은이보기에서 테이블을 만들고 TO_LOB을 사용하여이 필드를 CLOB으로 변환 한 다음 작업하는 것입니다.