2012-01-10 46 views
6

假设你有一个PL/SQL包用RECORD类型定义:元数据对于PL/SQL包级别的记录类型

CREATE OR REPLACE PACKAGE TEST_PACKAGE AS 

    TYPE PERSON_RECORD_TYPE IS RECORD 
    (
     first_name VARCHAR2(1000), 
     last_name VARCHAR2(1000) 
    ); 

END; 

有什么办法来获得包含在TEST_PACKAGE.PERSON_RECORD_TYPE字段列表?例如,有没有这种信息ALL_*的意见?

我不感兴趣模式种录像类型,只有种录像类型。

+0

从同一个包装内获得字段? – tbone 2012-01-10 14:11:10

+0

@tbone:不一定。我想从另一个包中获得这些字段。 – 2012-01-10 14:15:08

+1

“获得他们”的含义如何使用它们?你能给出一些伪代码,说明你在这个其他软件包中试图完成的任务吗? – tbone 2012-01-10 14:37:24

回答

1

下面是关于从软件包代码中检索信息的一些类似问题。

Find package global variables from data dictionary

Get Package Methods and Parameters from Oracle

我认为这是像第一个类似的问题。您无法通过视图访问这些字段。有解析源文本解决方案,这是丑陋的,或者你可能需要一个解决方法。

无论如何,我认为如果你需要这个,你的体系结构是错误的。

+0

难道这不会比回答更好吗? – Ollie 2012-01-10 14:25:30

+0

@Ollie我修复了我的答案,有点用处... – 2012-01-10 14:57:35

2

如果将PERSON_RECORD_TYPE用作某个过程或函数的参数或结果类型,则可以查询ALL_ARGUMENTS。这里的信息有点加密(记录和集合的多级封装层次被编码在POSITION,SEQUENCE和DATA_LEVEL列中),但它存在。

我不认为这样的问题指向错误的架构。对于自动PLSQL代码生成,这是完全合法的请求,不幸的是PLSQL语言支持非常弱。

0

jOOQ's code generator内部使用下面的查询,以可靠地找到所有包级别PL/SQL RECORD类型:

SELECT 
    "x"."TYPE_OWNER", 
    "x"."TYPE_NAME", 
    "x"."TYPE_SUBNAME","a".subprogram_id, 
    "a"."ARGUMENT_NAME" "ATTR_NAME", 
    "a"."SEQUENCE" "ATTR_NO", 
    "a"."TYPE_OWNER" "ATTR_TYPE_OWNER", 
    nvl2("a"."TYPE_SUBNAME", "a"."TYPE_NAME", NULL) "package_name", 
    COALESCE("a"."TYPE_SUBNAME", "a"."TYPE_NAME", "a"."DATA_TYPE") "ATTR_TYPE_NAME", 
    "a"."DATA_LENGTH" "LENGTH", 
    "a"."DATA_PRECISION" "PRECISION", 
    "a"."DATA_SCALE" "SCALE" 
FROM "SYS"."ALL_ARGUMENTS" "a" 
JOIN (
    SELECT 
    "a"."TYPE_OWNER", 
    "a"."TYPE_NAME", 
    "a"."TYPE_SUBNAME", 
    MIN("a"."OWNER") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "OWNER", 
    MIN("a"."PACKAGE_NAME") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "PACKAGE_NAME", 
    MIN("a"."SUBPROGRAM_ID") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "SUBPROGRAM_ID", 
    MIN("a"."SEQUENCE") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "SEQUENCE", 
    MIN("next_sibling") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "next_sibling", 
    MIN("a"."DATA_LEVEL") KEEP (DENSE_RANK FIRST 
     ORDER BY "a"."OWNER" ASC, "a"."PACKAGE_NAME" ASC, 
       "a"."SUBPROGRAM_ID" ASC, "a"."SEQUENCE" ASC) "DATA_LEVEL" 
    FROM (
    SELECT 
     lead("a"."SEQUENCE", 1, 99999999) OVER (
     PARTITION BY "a"."OWNER", "a"."PACKAGE_NAME", 
        "a"."SUBPROGRAM_ID", "a"."DATA_LEVEL" 
     ORDER BY "a"."SEQUENCE" ASC 
    ) "next_sibling", 
     "a"."TYPE_OWNER", 
     "a"."TYPE_NAME", 
     "a"."TYPE_SUBNAME", 
     "a"."OWNER", 
     "a"."PACKAGE_NAME", 
     "a"."SUBPROGRAM_ID", 
     "a"."SEQUENCE", 
     "a"."DATA_LEVEL", 
     "a"."DATA_TYPE" 
    FROM "SYS"."ALL_ARGUMENTS" "a" 
    WHERE "a"."OWNER" IN ('TEST')  -- Possibly replace schema here 
    ) "a" 
    WHERE ("a"."TYPE_OWNER" IN ('TEST') -- Possibly replace schema here 
    AND "a"."OWNER"   IN ('TEST') -- Possibly replace schema here 
    AND "a"."DATA_TYPE"  = 'PL/SQL RECORD') 
    GROUP BY 
    "a"."TYPE_OWNER", 
    "a"."TYPE_NAME", 
    "a"."TYPE_SUBNAME" 
) "x" 
ON (("a"."OWNER", "a"."PACKAGE_NAME", "a"."SUBPROGRAM_ID") 
= (("x"."OWNER", "x"."PACKAGE_NAME", "x"."SUBPROGRAM_ID")) 
AND "a"."SEQUENCE" BETWEEN "x"."SEQUENCE" AND "next_sibling" 
AND "a"."DATA_LEVEL" = ("x"."DATA_LEVEL" + 1)) 
ORDER BY 
    "x"."TYPE_OWNER" ASC, 
    "x"."TYPE_NAME" ASC, 
    "x"."TYPE_SUBNAME" ASC, 
    "a"."SEQUENCE" ASC 

在你的情况下,结果会是这样的:

TYPE_NAME  TYPE_SUBNAME  ATTR_NAME ATTR_TYPE_NAME LENGTH 
---------------------------------------------------------------------- 
TEST_PACKAGE PERSON_RECORD_TYPE FIRST_NAME VARCHAR2   1000 
TEST_PACKAGE PERSON_RECORD_TYPE LAST_NAME VARCHAR2   1000 

电流限制:

  • 查询将只查找那些重新生成的类型至少有一个其他类型和/或程序在某处。这是从查询中的ALL_ARGUMENTS字典视图继承的限制。
  • %ROWTYPE类型无法正确返回,因为未从TYPE_NAME/TYPE_SUBNAME列中引用行类型。

点击此处了解详情: https://blog.jooq.org/2016/11/08/use-jooq-to-read-write-oracle-plsql-record-types