【问题标题】:Get list of arguments with default value获取具有默认值的参数列表
【发布时间】:2012-11-27 23:50:13
【问题描述】:

我使用 ALL_ARGUMENTS 来获取 oracle 10g 中的参数列表,但我找不到参数的默认值。我该怎么办?

【问题讨论】:

  • 您是否正在寻找除ALL_ARGUMENTSDEFAULT_VALUE 列之外的其他内容(令人讨厌的是,LONG 使得使用它有点痛苦)?您在解释该列中的数据时遇到问题吗?
  • @user1662382:我认为default_value列是reserved for future use,如文档link中所述,还有一个错误#393152,尚未修复。
  • 在 11g 中 [all_arguments] 的 [defaulted] 列中显示参数是否具有默认值。 10g中不存在这个专栏,我尝试寻找另一种简单的方法。

标签: oracle oracle10g


【解决方案1】:

您可能需要在 10g 中使用 plsql 编程,就像下面的代码示例一样。这个解决方案在某种意义上肯定是蛮力的,因为您基本上使用非常低级的原语编写函数/过程声明解析器的一部分。但是,正则表达式函数在 10g 中也不可用...

代码的要点是:

  • 遍历过程/函数声明的源代码行
  • 注意最近声明的例程的名称
  • 分析包含关键字“DEFAULT”的所有行,获取参数名称和默认值规范(代码示例中没有详细说明)。

提防陷阱:

  • 多行声明
  • 包含 C 样式注释开头字符串的 C 样式 cmets ( a la /* blah blah / blah blah **/ )
  • 包含关键字的字符串文字

希望对您有所帮助,最好的问候。

代码:

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;

【讨论】:

    【解决方案2】:

    我知道这有点太晚了,但这可能会有所帮助。我现在面临着类似的问题。需要更多测试...

    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
     /
    

    【讨论】:

      【解决方案3】:

      在视图SYS.ALL_ARGUMENTS 中有一个名为DEFAULT_VALUE 的列,但即使在11g 中,它的类型也是LONG,并且要解决并转换为CLOB 是一件令人头疼的事情。

      “最简单”(不是最好)的方法是从此视图创建一个表,使用 TO_LOB 将此字段转换为 CLOB 并使用它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-08-11
        • 2016-10-30
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2014-03-09
        • 2017-03-09
        相关资源
        最近更新 更多