包定义中的 Oracle 用户定义类型

Posted

技术标签:

【中文标题】包定义中的 Oracle 用户定义类型【英文标题】:Oracle User defined type inside package definition 【发布时间】:2012-01-08 02:29:22 【问题描述】:

是否可以在 Oracle 包定义中包含用户定义类型?当我尝试关注时

CREATE OR REPLACE PACKAGE AF_CONTRACT AS  -- spec
   -- PROCEDURE my_rpcedure (emp_id NUMBER);
   TYPE DTO_GRID AS OBJECT
   (
     ROWKEY    NVARCHAR2(200),
     COLUMNKEY NVARCHAR2(200),
     CELLVALUE NVARCHAR2(200),
     OLDVALUE  NVARCHAR2(200),
     TAG       NVARCHAR2(200)
   );
END AF_CONTRACT;
/
CREATE OR REPLACE PACKAGE BODY AF_CONTRACT AS  -- body

--   PROCEDURE my_procedure (emp_id NUMBER) IS
--   BEGIN
--      
--   END my_procedure;

END AF_CONTRACT;

总是出错

Error: PLS-00540: object not supported in this context.

在类型定义中。

【问题讨论】:

【参考方案1】:

对象类型必须在数据库级别声明。您可以在包规范中声明集合类型。

可能重复: Possible to create Oracle Database object types inside of PL/SQL?

【讨论】:

【参考方案2】:

不,这是不允许的:

SQL> CREATE OR REPLACE PACKAGE AF_CONTRACT AS  -- spec
   -- PROCEDURE my_rpcedure (emp_id NUMBER);
   TYPE DTO_GRID AS OBJECT
   (
     ROWKEY    NVARCHAR2(200),
     COLUMNKEY NVARCHAR2(200),
     CELLVALUE NVARCHAR2(200),
     OLDVALUE  NVARCHAR2(200),
     TAG       NVARCHAR2(200)
   );
END AF_CONTRACT;
/
  2    3    4    5    6    7    8    9   10   11   12

Warning: Package created with compilation errors.

SQL> SQL> sho err
Errors for PACKAGE AF_CONTRACT:

LINE/COL ERROR
-------- -----------------------------------------------------------------
3/4      PLS-00540: object not supported in this context.
SQL>

如果你想创建一个在 PL/SQL 过程之间传递数据的类型,那么使用 PL/SQL RECORD 语法:

SQL> CREATE OR REPLACE PACKAGE AF_CONTRACT AS  -- spec
   -- PROCEDURE my_rpcedure (emp_id NUMBER);
   TYPE DTO_GRID IS RECORD
   (
     ROWKEY    NVARCHAR2(200),
     COLUMNKEY NVARCHAR2(200),
     CELLVALUE NVARCHAR2(200),
     OLDVALUE  NVARCHAR2(200),
     TAG       NVARCHAR2(200)
   );
END AF_CONTRACT;
/
  2    3    4    5    6    7    8    9   10   11   12
Package created.

SQL>

但是,如果您想要一个可以在 SQL 语句中使用的类型 - 即作为 TABLE() 函数的输入 - 您需要将其创建为 SQL 类型。 SQL 和 PL/SQL 使用两种不同的引擎,并且只有 SQL 类型对 SQL 引擎可见。


我关于 SQL 类型必要性的建议不再适用于更高版本的 Oracle。当然,在 11gR2 和 12c 中,SQL 引擎将支持 PL/SQL 包中的 SQL,它在 TABLE() 子句中使用 PL/SQL 表。类型必须在包规范中声明,因此对 SQL 引擎是公开的和可见的。在幕后,Oracle 为每个声明生成 SQL 类型。您可以发现这些类型,因为它们的名称以 SYS_PLSQL_ 开头,后跟数字标识符。

【讨论】:

以上是关于包定义中的 Oracle 用户定义类型的主要内容,如果未能解决你的问题,请参考以下文章

Oracle使用包中定义的类型作为添加到已定义类型的表的记录

如何在java中调用包含用户定义类型的oracle存储过程?

通过数据库链接在 oracle 中调用存储函数(返回用户定义类型的数组)

在某些参数类型是用户定义的情况下,如何使用 JDBC/Spring 调用 Oracle 存储过程?

oracle 自定义函数,调用时报“程序包或函数无效”

oraclede中数据定义语言