2012-12-10 50 views
4

我使用ALL_ARGUMENTS獲取oracle 10g中的參數列表,但是我找不到參數的默認值。唧我能做到嗎?獲取具有默認值的參數列表

+0

您是否正在尋找除'ALL_ARGUMENTS'的'DEFAULT_VALUE'列之外的其他東西?(令人討厭的是,'LONG'使它有點痛苦)?您是否在解釋該列中的數據時遇到問題? –

+1

@ user1662382:我認爲如文檔[link](http://docs.oracle.com/cd/B28359_01/server.111/b28320/statviews_1014.htm)中所提到的那樣,default_value列「保留供將來使用」,還有一個錯誤#393152,這還沒有修復。 –

+0

在11g中,[all_arguments]中的[默認]列顯示參數是否具有默認值。本專欄不存在於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

我知道這是一個有點晚了,但是這可能會有所幫助。我目前面臨類似的問題。需要更多的測試...

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

在視圖SYS.ALL_ARGUMENTS有一個名爲DEFAULT_VALUE列,但即使在11g中它的類型爲LONG,是一個令人頭疼的解決,並轉換爲CLOB。

「最簡單的」(不是最好的)方法是使用TO_LOB將該字段轉換爲CLOB並使用該視圖創建此視圖中的表格。