2012-01-10 14 views
6

Suponga que tiene un paquete PL/SQL con un tipo definido RECORD:metadatos con respecto a/SQL tipos de registros a nivel de paquete PL

CREATE OR REPLACE PACKAGE TEST_PACKAGE AS 

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

END; 

¿Hay alguna manera de obtener una lista de los campos contenidos en TEST_PACKAGE.PERSON_RECORD_TYPE? Por ejemplo, ¿hay alguna vista ALL_* con esta información?

No estoy interesado en esquema de tipos de registro, solamente -level paquete tipos de registro -level.

+0

obtener los campos desde dentro del mismo paquete? – tbone

+0

@tbone: No necesariamente. Me gustaría obtener los campos de un paquete diferente. –

+1

"obtenerlos", que significa usarlos ¿cómo? ¿Puedes dar algún pseudo código de lo que estás tratando de lograr en este otro paquete? – tbone

Respuesta

1

Aquí hay algunas preguntas similares sobre cómo recuperar información del código del paquete.

Find package global variables from data dictionary

Get Package Methods and Parameters from Oracle

que ver esto como un problema similar como el primero. No puede acceder a esos campos a través de una vista. Existe la solución de texto fuente de análisis sintáctico, que es fea, o puede que necesite una solución alternativa a esto.

De todos modos, creo que es algo malo en su arquitectura si lo necesita.

+0

¿no sería mejor esto como un comentario que como una respuesta? – Ollie

+0

@Ollie Reedite mi respuesta para ser un poco útil ... –

2

Si PERSON_RECORD_TYPE se usa como argumento o tipo de resultado de algún procedimiento o función, puede consultar ALL_ARGUMENTS. La información está un poco cifrada allí (la jerarquía de encapsulación multinivel de registros y colecciones está codificada en columnas POSICIÓN, SECUENCIA y NIVEL_DATOS), sin embargo, está presente.

No creo que esa pregunta apunte a la arquitectura incorrecta. Para la generación automática de código PLSQL, esta es una solicitud completamente legítima, desafortunadamente con soporte de lenguaje PLSQL muy débil.

0

jOOQ's code generator internamente utiliza la siguiente consulta para encontrar de forma fiable todos los nivel de paquete PL/SQL RECORD tipos:

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 

En su caso, el resultado será algo como:

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 

limitaciones actuales:

  • La consulta solo encontrará los tipos que son re Ferenced por al menos otro tipo y/o procedimiento en alguna parte. Esta es una limitación heredada de la vista del diccionario ALL_ARGUMENTS en la consulta.
  • %ROWTYPE tipos no se devuelven correctamente porque el tipo de fila no se hace referencia a partir de las columnas TYPE_NAME/TYPE_SUBNAME.

Más información aquí: https://blog.jooq.org/2016/11/08/use-jooq-to-read-write-oracle-plsql-record-types

Cuestiones relacionadas