Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Oracle User defined type inside package definition

is it possible to have a User Defined Type inside Oracle package definition? When I try following

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;

I always get an error

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

in the type definition.

like image 930
llasarov Avatar asked Nov 28 '11 16:11

llasarov


People also ask

What is user-defined data type in Oracle?

User-defined datatypes use the built-in datatypes and other user-defined datatypes as the building blocks for datatypes that model the structure and behavior of data in applications. User-defined types are schema objects. Their use is subject to the same kinds of administrative control as other schema objects.

Can we have a function or procedure declared in package specification and not defined in package body and why?

Can we create a package Specification without body ? Yes, and these are quite useful when the package only contains variable and/or type declarations, e.g.

Which package construct must be declared and defined within the packages body?

Package Specification All objects placed in the specification are called public objects. Any subprogram not in the package specification but coded in the package body is called a private object.


1 Answers

No, it's not permitted:

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>

If you want to create a type which is just passing data between PL/SQL procedures then use the PL/SQL RECORD syntax:

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>

However, if you want a type which you can use in a SQL statement - that is, as the input to a TABLE() function - you will need to create it as a SQL type. SQL and PL/SQL use two different engines, and only SQL types are visible to the SQL engine.


My advice about the necessity of SQL Types is no longer true for later versions of Oracle. Certainly in 11gR2 and 12c the SQL engine will support SQL in PL/SQL packages which uses PL/SQL tables in a TABLE() clause. The Types have to be declared in the package spec, hence public and visible to the SQL engine. Under the covers Oracle generates SQL types for each declaration. You can spot these Types because their names start SYS_PLSQL_ followed by numeric identifiers.

like image 157
APC Avatar answered Oct 26 '22 07:10

APC