3

我一直在研究如何在不使用 '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: 句子 SQL 无效 ORA-06512: 在线 12

当像这样修改“x”变量时:

x := 'BEGIN DESCRIBE '||item.OBJECT_NAME||'; END;';

我收到以下错误:

错误在线路 1:ORA-06550:线路 1,第 16 列:PLS-00103:在预期以下情况之一时遇到符号“BVGKFDCS”::=。( @ % ; 符号 ":=" 被替换为 "BVGKFDCS" 以继续。ORA-06512: en línea 12

其中“BVGKFDCS”是我的架构中一个包的名称。

提前致谢。

PD 我想得到类似的东西(但对于每个包裹):

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
4

4 回答 4

5

看看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
于 2015-05-06T22:03:27.233 回答
2

您需要使用 User_Source、DBA_SOURCE 或 All_Source。所有代码都存储在那里。

select text 
from user_source
where name = 'procedure_name' 
order by line;

对象类型:FUNCTION、JAVA SOURCE、PACKAGEPACKAGE BODY、PROCEDURE、TRIGGER、TYPE、TYPE BODY

于 2015-05-06T20:16:35.920 回答
0

describe不起作用,execute immediate因为它是 SQL*Plus 命令,而不是 SQL 或 PL/SQL 命令的一部分。它由客户端而不是服务器解释。

正如@TS 所建议的,获取任何数据库对象(包括包和包主体)的源的最佳方法是DBA_SOURCEor 。USER_SOURCE

数据库中的每种对象都有数据字典视图。当尝试为其他对象类型获取类似类型的数据时,您应该引用dictionary视图,这有助于对数据字典进行编目。例如,dictionary条目为user_source

TABLE_NAME  | COMMENTS
------------+------------------------------------------------
USER_SOURCE | Source of stored objects accessible to the user

过程名称是包规范的一部分。all_source使用包名进行查询,type='package'将返回规范,包括所有公共过程及其参数。

于 2015-05-06T21:03:51.553 回答
-1

这对你有用吗?

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>
于 2015-05-06T20:50:49.453 回答