如何在不使用 DESCRIBE 子句的情况下描述 ORACLE 包?
How to describe an ORACLE package without using DESCRIBE clause?
我一直在研究如何在不使用 'DESCRIBE table/view;' 子句的情况下描述 TABLES 和 VIEWS。我发现它可以使用类似的东西来解决:
SELECT column_name, data_type, data_length, data_precision, data_scale, nullable
FROM all_tab_columns
WHERE table_name = 'TABLE'
它可以用 PHP 这样的计算机语言完美编程,但我没有找到 'DESCRIBE package_name' 子句的解决方法。
我有以下想法(但在 SQL*PLUS 中有一个线轴):
DECLARE
x VARCHAR2(50);
CURSOR cursorPaquetes IS
SELECT DISTINCT OBJECT_NAME
FROM ALL_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE' AND OWNER = 'SATURN';
BEGIN
FOR item IN cursorPaquetes LOOP
x := 'DESCRIBE '||item.OBJECT_NAME||';';
EXECUTE IMMEDIATE x;
END LOOP;
END;
但它没有用:(。抛出以下错误:
ORA-00900: sentencia SQL no válida ORA-06512: en línea 12
并且像这样修改 'x' 变量时:
x := 'BEGIN DESCRIBE '||item.OBJECT_NAME||'; END;';
我收到以下错误:
ERROR en línea 1: ORA-06550: línea 1, columna 16: PLS-00103:
Encountered the symbol "BVGKFDCS" when expecting one of the following:
:= . ( @ % ; The symbol ":=" was substituted for "BVGKFDCS" to
continue. ORA-06512: en línea 12
其中 "BVGKFDCS" 是我的模式的其中一个包的名称。
提前致谢。
P.D。我想得到类似的东西(但对于每个包裹):
DESCRIBE BVGKFDCS;
PROCEDURE P_GETPROFESSORS
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
P_CAMP_IN VARCHAR2 IN
P_COLL_IN VARCHAR2 IN
P_DEPT_IN VARCHAR2 IN
P_TERM_IN VARCHAR2 IN
PROCEDURE P_GETTERMSBYPROF
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
NAME_ARRAY TABLE OF VARCHAR2(32000) IN
VALUE_ARRAY TABLE OF VARCHAR2(32000) IN
PROCEDURE P_INIT
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
PIDM VARCHAR2 IN
PROCEDURE P_OBTENER_VALOR
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
请注意,此输出不同于:
select * from user_source
您需要使用 User_Source、DBA_SOURCE 或 All_Source。所有代码都存储在那里。
select text
from user_source
where name = 'procedure_name'
order by line;
对象类型:FUNCTION,JAVA SOURCE,PACKAGE,PACKAGE BODY,PROCEDURE,TRIGGER,TYPE,TYPE正文
这对你有用吗?
SQL> SELECT DBMS_METADATA.GET_DDL('PACKAGE','EMP_PKG','SCOTT') FROM DUAL;
SQL> SELECT DBMS_METADATA.GET_DDL('PACKAGE_BODY','EMP_PKG','SCOTT') FROM DUAL;
SQL> show user
USER is "SYSTEM"
SQL>
SQL> l
1* SELECT DBMS_METADATA.GET_DDL('PROCEDURE','P1','HR') FROM DUAL
SQL> /
DBMS_METADATA.GET_DDL('PROCEDURE','P1','HR')
-----------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE "HR"."P1" ( p_id int) as
begin
dbms_output.put
SQL>
describe
在 execute immediate
中不起作用,因为它是 SQL*Plus 命令,而不是 SQL 或 PL/SQL 的一部分命令。它由客户端解释,而不是服务器。
获取任何数据库对象(包括包和包主体)的源代码的最佳方法是 DBA_SOURCE
或 USER_SOURCE
,正如@T.S..[= 所建议的那样20=]
数据库中的每种对象都有数据字典视图。当尝试为其他对象类型获取类似类型的数据时,您应该引用 dictionary
视图,它有助于对数据字典进行编目。例如,user_source
的 dictionary
条目是:
TABLE_NAME | COMMENTS
------------+------------------------------------------------
USER_SOURCE | Source of stored objects accessible to the user
过程名称是程序包规范的一部分。使用包名称和 type='package'
查询 all_source
将 return 规范,包括所有 public 过程及其参数。
看看USER_PROCEDURES
。我怀疑这就是当您在包、过程或函数上使用 DESCRIBE 时查询的内容。
编辑:抱歉,还包含 USER_ARGUMENTS
以列出每个子程序的参数。由于处理不同对象类型的方式,连接两个视图的逻辑不是很明显。这个查询看起来产生了合理的结果,但我没有仔细检查结果:
SELECT * FROM all_arguments A
JOIN all_procedures p
ON ( ( p.object_type = 'PACKAGE' AND A.package_name = p.object_name AND A.object_name = p.procedure_name)
OR
( p.object_type <> 'PACKAGE' AND A.package_name IS NULL AND A.object_name = p.object_name )
)
AND p.owner = A.owner
我一直在研究如何在不使用 'DESCRIBE table/view;' 子句的情况下描述 TABLES 和 VIEWS。我发现它可以使用类似的东西来解决:
SELECT column_name, data_type, data_length, data_precision, data_scale, nullable
FROM all_tab_columns
WHERE table_name = 'TABLE'
它可以用 PHP 这样的计算机语言完美编程,但我没有找到 'DESCRIBE package_name' 子句的解决方法。
我有以下想法(但在 SQL*PLUS 中有一个线轴):
DECLARE
x VARCHAR2(50);
CURSOR cursorPaquetes IS
SELECT DISTINCT OBJECT_NAME
FROM ALL_OBJECTS
WHERE OBJECT_TYPE = 'PACKAGE' AND OWNER = 'SATURN';
BEGIN
FOR item IN cursorPaquetes LOOP
x := 'DESCRIBE '||item.OBJECT_NAME||';';
EXECUTE IMMEDIATE x;
END LOOP;
END;
但它没有用:(。抛出以下错误:
ORA-00900: sentencia SQL no válida ORA-06512: en línea 12
并且像这样修改 'x' 变量时:
x := 'BEGIN DESCRIBE '||item.OBJECT_NAME||'; END;';
我收到以下错误:
ERROR en línea 1: ORA-06550: línea 1, columna 16: PLS-00103: Encountered the symbol "BVGKFDCS" when expecting one of the following: := . ( @ % ; The symbol ":=" was substituted for "BVGKFDCS" to continue. ORA-06512: en línea 12
其中 "BVGKFDCS" 是我的模式的其中一个包的名称。
提前致谢。
P.D。我想得到类似的东西(但对于每个包裹):
DESCRIBE BVGKFDCS;
PROCEDURE P_GETPROFESSORS
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
P_CAMP_IN VARCHAR2 IN
P_COLL_IN VARCHAR2 IN
P_DEPT_IN VARCHAR2 IN
P_TERM_IN VARCHAR2 IN
PROCEDURE P_GETTERMSBYPROF
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
NAME_ARRAY TABLE OF VARCHAR2(32000) IN
VALUE_ARRAY TABLE OF VARCHAR2(32000) IN
PROCEDURE P_INIT
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
PIDM VARCHAR2 IN
PROCEDURE P_OBTENER_VALOR
Nombre de Argumento Tipo E/S ¿Por Defecto?
------------------------------ ----------------------- ------ --------
请注意,此输出不同于:
select * from user_source
您需要使用 User_Source、DBA_SOURCE 或 All_Source。所有代码都存储在那里。
select text
from user_source
where name = 'procedure_name'
order by line;
对象类型:FUNCTION,JAVA SOURCE,PACKAGE,PACKAGE BODY,PROCEDURE,TRIGGER,TYPE,TYPE正文
这对你有用吗?
SQL> SELECT DBMS_METADATA.GET_DDL('PACKAGE','EMP_PKG','SCOTT') FROM DUAL;
SQL> SELECT DBMS_METADATA.GET_DDL('PACKAGE_BODY','EMP_PKG','SCOTT') FROM DUAL;
SQL> show user
USER is "SYSTEM"
SQL>
SQL> l
1* SELECT DBMS_METADATA.GET_DDL('PROCEDURE','P1','HR') FROM DUAL
SQL> /
DBMS_METADATA.GET_DDL('PROCEDURE','P1','HR')
-----------------------------------------------------------------------------
CREATE OR REPLACE PROCEDURE "HR"."P1" ( p_id int) as
begin
dbms_output.put
SQL>
describe
在 execute immediate
中不起作用,因为它是 SQL*Plus 命令,而不是 SQL 或 PL/SQL 的一部分命令。它由客户端解释,而不是服务器。
获取任何数据库对象(包括包和包主体)的源代码的最佳方法是 DBA_SOURCE
或 USER_SOURCE
,正如@T.S..[= 所建议的那样20=]
数据库中的每种对象都有数据字典视图。当尝试为其他对象类型获取类似类型的数据时,您应该引用 dictionary
视图,它有助于对数据字典进行编目。例如,user_source
的 dictionary
条目是:
TABLE_NAME | COMMENTS
------------+------------------------------------------------
USER_SOURCE | Source of stored objects accessible to the user
过程名称是程序包规范的一部分。使用包名称和 type='package'
查询 all_source
将 return 规范,包括所有 public 过程及其参数。
看看USER_PROCEDURES
。我怀疑这就是当您在包、过程或函数上使用 DESCRIBE 时查询的内容。
编辑:抱歉,还包含 USER_ARGUMENTS
以列出每个子程序的参数。由于处理不同对象类型的方式,连接两个视图的逻辑不是很明显。这个查询看起来产生了合理的结果,但我没有仔细检查结果:
SELECT * FROM all_arguments A
JOIN all_procedures p
ON ( ( p.object_type = 'PACKAGE' AND A.package_name = p.object_name AND A.object_name = p.procedure_name)
OR
( p.object_type <> 'PACKAGE' AND A.package_name IS NULL AND A.object_name = p.object_name )
)
AND p.owner = A.owner