TYPE statement creates or replaces the specification of an object type, a SQLJ object type, a named varying array (varray), a nested table type, or an incomplete object type. You create object types with the
TYPE and the
BODY statements. The
TYPE statement specifies the name of the object type, its attributes, methods, and other properties. The
BODY statement contains the code for the methods that implement the type.
If you create an object type for which the type specification declares only attributes but no methods, then you need not specify a type body.
If you create a SQLJ object type, then you cannot specify a type body. The implementation of the type is specified as a Java class.
An incomplete type is a type created by a forward type definition. It is called "incomplete" because it has a name but no attributes or methods. It can be referenced by other types, and so can be used to define types that refer to each other. However, you must fully specify the type before you can use it to create a table or an object column or a column of a nested table type.
Note:A standalone stored type that you create with the
TYPEstatement is different from a type that you define in a PL/SQL block or package. For information about the latter, see Collection.
TYPE statement, you can create nested table and varray types, but not associative arrays. In a PL/SQL block or package, you can define all three collection types.
To create a type in your own schema, you must have the
TYPE system privilege. To create a type in another user's schema, you must have the
TYPE system privilege. You can acquire these privileges explicitly or be granted them through a role.
To create a subtype, you must have the
TYPE system privilege or the
UNDER object privilege on the supertype.
The owner of the type must be explicitly granted the
EXECUTE object privilege in order to access all other types referenced within the definition of the type, or the type owner must be granted the
TYPE system privilege. The owner cannot obtain these privileges through roles.
If the type owner intends to grant other users access to the type, then the owner must be granted the
EXECUTE object privilege on the referenced types with the
OPTION or the
TYPE system privilege with the
OPTION. Otherwise, the type owner has insufficient privileges to grant access on the type to other users.
REPLACE to re-create the type if it already exists. Use this clause to change the definition of an existing type without first dropping it.
Users previously granted privileges on the re-created object type can use and reference the object type without being granted privileges again.
If any function-based indexes depend on the type, then the database marks the indexes
Specify the schema to contain the type. If you omit
schema, then the database creates the type in your current schema.
Specify the name of an object type, a nested table type, or a varray type.
If creating the type results in compilation errors, then the database returns an error. You can see the associated compiler error messages with the SQL*Plus command
The database implicitly defines a constructor method for each user-defined type that you create. A constructor is a system-supplied procedure that is used in SQL statements or in PL/SQL code to construct an instance of the type value. The name of the constructor method is the same as the name of the user-defined type. You can also create a user-defined constructor using the
The parameters of the object type constructor method are the data attributes of the object type. They occur in the same order as the attribute definition order for the object type. The parameters of a nested table or varray constructor are the elements of the nested table or the varray.
object_type clause to create a user-defined object type. The variables that form the data structure are called attributes. The member subprograms that define the behavior of the object are called methods. The keywords
OBJECT are required when creating an object type.
See Also:Object Type Examples
OID clause is useful for establishing type equivalence of identical objects in more than one database. (OID is short for Oracle Internet Directory.) See Oracle Database Object-Relational Developer's Guide for information about this clause.
AUTHID property of the member functions and procedures of the object type. For information about the
AUTHID property, see "Using Invoker's Rights or Definer's Rights (AUTHID Clause)".
You can specify this clause only for an object type, not for a nested table or varray type.
You can specify this clause for clarity if you are creating a subtype. However, subtypes inherit the rights model of their supertypes, so you cannot specify a different value than was specified for the supertype.
If the supertype was created with definer's rights, then you must create the subtype in the same schema as the supertype.
See Also:Using Invoker's Rights or Definer's Rights (AUTHID Clause) for more information about the
OBJECT to create a top-level object type. Such object types are sometimes called root object types.
supertype to create a subtype of an existing type. The existing supertype must be an object type. The subtype you create in this statement inherits the properties of its supertype. It must either override some of those properties or add new properties to distinguish it from the supertype.
Specify this clause to create a SQLJ object type. In a SQLJ object type, you map a Java class to a SQL user-defined type. You can then define tables or columns on the SQLJ object type as you would with any other user-defined type.
You can map one Java class to multiple SQLJ object types. If there exists a subtype or supertype of a SQLJ object type, then it must also be a SQLJ object type. All types in the hierarchy must be SQLJ object types.
See Also:Oracle Database Object-Relational Developer's Guide for more information about creating SQLJ object types
Multiple SQLJ object types can be mapped to the same class. However:
A subtype must be mapped to a class that is an immediate subclass of the class to which its supertype is mapped.
Two subtypes of a common supertype cannot be mapped to the same class.
See Also:Oracle Database JDBC Developer's Guide and Reference for information about these three interfaces and SQLJ Object Type Example
element_spec lets you specify each attribute of the object type.
attribute, specify the name of an object attribute. Attributes are data items with a name and a type specifier that form the structure of the object. You must specify at least one attribute for each object type.
If you are creating a subtype, then the attribute name cannot be the same as any attribute or method name declared in the supertype chain.
datatype, specify the database built-in data type or user-defined type of the attribute.
You cannot specify attributes of type
You cannot specify a data type of
UROWID for a user-defined object type.
If you specify an object of type
REF, then the target object must have an object identifier.
If you are creating a collection type for use as a nested table or varray column of a table, then you cannot specify attributes of type
See Also:Chapter 3, "PL/SQL Data Types," for a list of valid data types
This clause is valid only if you have specified the
sqlj_object_type clause to map a Java class to a SQLJ object type. Specify the external name of the Java field that corresponds to the attribute of the SQLJ object type. The Java
field_name must already exist in the class. You cannot map a Java
field_name to more than one SQLJ object type attribute in the same type hierarchy.
This clause is optional when you create a SQLJ object type.
subprogram_spec lets you associate a procedure subprogram with the object type.
Specify a function or procedure subprogram associated with the object type that is referenced as an attribute. Typically, you invoke
MEMBER methods in a selfish style, such as
(). This class of method has an implicit first argument referenced as
SELF in the method body, which represents the object on which the method has been invoked.
See Also:Creating a Member Method: Example
Specify a function or procedure subprogram associated with the object type. Unlike
STATIC methods do not have any implicit parameters. You cannot reference
SELF in their body. They are typically invoked as
You cannot map a
MEMBER method in a Java class to a
STATIC method in a SQLJ object type.
STATIC methods, you must specify a corresponding method body in the object type body for each procedure or function specification.
See Also:Creating a Static Method: Example
At the top level of the syntax, these clauses specify the inheritance attributes of the type.
Use the [
FINAL clause to indicate whether any further subtypes can be created for this type:
FINAL if no further subtypes can be created for this type. This is the default.
FINAL if further subtypes can be created under this type.
Use the [
INSTANTIABLE clause to indicate whether any object instances of this type can be constructed:
INSTANTIABLE if object instances of this type can be constructed. This is the default.
INSTANTIABLE if no default or user-defined constructor exists for this object type. You must specify these keywords for any type with noninstantiable methods and for any type that has no attributes, either inherited or specified in this statement.
As part of the
inheritance_clauses let you specify the relationship between supertypes and subtypes.
OVERRIDING This clause is valid only for
MEMBER methods. Specify
OVERRIDING to indicate that this method overrides a
MEMBER method defined in the supertype. This keyword is required if the method redefines a supertype method.
OVERRIDING is the default.
Use these clauses to specify the parameters and data types of the procedure or function. If this subprogram does not include the declaration of the procedure or function, then you must issue a corresponding
Restriction on Procedure and Function Specification If you are creating a subtype, then the name of the procedure or function cannot be the same as the name of any attribute, whether inherited or not, declared in the supertype chain.
If you are mapping a Java class to a SQLJ object type and you specify
NAME, then the value of the Java method returned must be compatible with the SQL returned value, and the Java method must be public. Also, the method signature (method name plus parameter types) must be unique within the type hierarchy.
If you specify
NAME, then the type of the Java static field must be compatible with the return type.
Specify the call specification that maps a Java or C method name, parameter types, and return type to their SQL counterparts. If all the member methods in the type have been defined in this clause, then you need not issue a corresponding
Java_declaration string identifies the Java implementation of the method.
Oracle Database Java Developer's Guide for an explanation of the parameters and semantics of the
Oracle Database Advanced Application Developer's Guide for information about calling external procedures
pragma_clause lets you specify a compiler directive. The
RESTRICT_REFERENCES compiler directive denies member functions read/write access to database tables, packaged variables, or both, and thereby helps to avoid side effects.
Note:Oracle recommends that you avoid using this clause unless you must do so for backward compatibility of your applications. This clause has been deprecated, because the database now runs purity checks at run time.
See Also:RESTRICT_REFERENCES Pragma for more information about this pragma
Use this clause to create a user-defined constructor, which is a function that returns an initialized instance of a user-defined object type. You can declare multiple constructors for a single object type, as long as the parameters of each constructor differ in number, order, or data type.
User-defined constructor functions are always
INSTANTIABLE, so these keywords are optional.
The parameter-passing mode of user-defined constructors is always
OUT. Therefore you need not specify this clause unless you want to do so for clarity.
RESULT specifies that the run-time type of the value returned by the constructor is the same as the run-time type of the
See Also:Oracle Database Object-Relational Developer's Guide for more information about and examples of user-defined constructors and Constructor Example
You can define either one
MAP method or one
ORDER method in a type specification, regardless of how many
STATIC methods you define. If you declare either method, then you can compare object instances in SQL.
You cannot define either
ORDER methods for subtypes. However, a subtype can override a
MAP method if the supertype defines a nonfinal
MAP method. A subtype cannot override an
ORDER method at all.
You can specify either
ORDER when mapping a Java class to a SQL type. However, the
ORDER methods must map to
MEMBER functions in the Java class.
If neither a
MAP nor an
ORDER method is specified, then only comparisons for equality or inequality can be performed. Therefore object instances cannot be ordered. Instances of the same type definition are equal only if each pair of their corresponding attributes is equal. No comparison method must be specified to determine the equality of two object types.
MAP if you are performing extensive sorting or hash join operations on object instances.
MAP is applied once to map the objects to scalar values, and then the database uses the scalars during sorting and merging. A
MAP method is more efficient than an
ORDER method, which must invoke the method for each object comparison. You must use a
MAP method for hash joins. You cannot use an
ORDER method because the hash mechanism hashes on the object value.
See Also:Oracle Database Object-Relational Developer's Guide for more information about object value comparisons
MAP MEMBER This clause lets you specify a
MAP member function that returns the relative position of a given instance in the ordering of all instances of the object. A
MAP method is called implicitly and induces an ordering of object instances by mapping them to values of a predefined scalar type. PL/SQL uses the ordering to evaluate Boolean expressions and to perform comparisons.
If the argument to the
MAP method is null, then the
MAP method returns null and the method is not invoked.
An object specification can contain only one
MAP method, which must be a function. The result type must be a predefined SQL scalar type, and the
MAP method can have no arguments other than the implicit
type_namewill be referenced in queries containing sorts (through an
UNIONclause) or containing joins, and you want those queries to be parallelized, then you must specify a
A subtype cannot define a new
MAP method. However it can override an inherited
ORDER MEMBER This clause lets you specify an
ORDER member function that takes an instance of an object as an explicit argument and the implicit
SELF argument and returns either a negative, zero, or positive integer. The negative, positive, or zero indicates that the implicit
SELF argument is less than, equal to, or greater than the explicit argument.
If either argument to the
ORDER method is null, then the
ORDER method returns null and the method is not invoked.
When instances of the same object type definition are compared in an
BY clause, the
map_order_function_spec is invoked.
An object specification can contain only one
ORDER method, which must be a function having the return type
A subtype can neither define nor override an
varray_type_def clause lets you create the type as an ordered set of elements, each of which has the same data type.
Restrictions on Varray Types You can create a
VARRAY type of
XMLType or of a LOB type for procedural purposes, for example, in PL/SQL or in view queries. However, database storage of such a varray is not supported, so you cannot create an object table or an object type column of such a varray type.
See Also:Varray Type Example
nested_table_type_def clause lets you create a named nested table of type
Object Type Examples The following example shows how the sample type
customer_typ was created for the sample Order Entry (
oe) schema. A hypothetical name is given to the table so that you can duplicate this example in your test database:
CREATE TYPE customer_typ_demo AS OBJECT ( customer_id NUMBER(6) , cust_first_name VARCHAR2(20) , cust_last_name VARCHAR2(20) , cust_address CUST_ADDRESS_TYP , phone_numbers PHONE_LIST_TYP , nls_language VARCHAR2(3) , nls_territory VARCHAR2(30) , credit_limit NUMBER(9,2) , cust_email VARCHAR2(30) , cust_orders ORDER_LIST_TYP ) ; /
In the following example, the
data_typ1 object type is created with one member function
prod, which is implemented in the
CREATE TYPE data_typ1 AS OBJECT ( year NUMBER, MEMBER FUNCTION prod(invent NUMBER) RETURN NUMBER ); / CREATE TYPE BODY data_typ1 IS MEMBER FUNCTION prod (invent NUMBER) RETURN NUMBER IS BEGIN RETURN (year + invent); END; END; /
Subtype Example The following statement shows how the subtype
corporate_customer_typ in the sample
oe schema was created. It is based on the
customer_typ supertype created in the preceding example and adds the
account_mgr_id attribute. A hypothetical name is given to the table so that you can duplicate this example in your test database:
CREATE TYPE corporate_customer_typ_demo UNDER customer_typ ( account_mgr_id NUMBER(6) );
SQLJ Object Type Example The following examples create a SQLJ object type and subtype. The
address_t type maps to the Java class
Examples.Address. The subtype
long_address_t maps to the Java class
Examples.LongAddress. The examples specify SQLData as the mechanism used to create the Java instance of these types. Each of the functions in these type specifications has a corresponding implementation in the Java class.
See Also:Oracle Database Object-Relational Developer's Guide for the Java implementation of the functions in these type specifications
CREATE TYPE address_t AS OBJECT EXTERNAL NAME 'Examples.Address' LANGUAGE JAVA USING SQLData( street_attr varchar(250) EXTERNAL NAME 'street', city_attr varchar(50) EXTERNAL NAME 'city', state varchar(50) EXTERNAL NAME 'state', zip_code_attr number EXTERNAL NAME 'zipCode', STATIC FUNCTION recom_width RETURN NUMBER EXTERNAL VARIABLE NAME 'recommendedWidth', STATIC FUNCTION create_address RETURN address_t EXTERNAL NAME 'create() return Examples.Address', STATIC FUNCTION construct RETURN address_t EXTERNAL NAME 'create() return Examples.Address', STATIC FUNCTION create_address (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int) return Examples.Address', STATIC FUNCTION construct (street VARCHAR, city VARCHAR, state VARCHAR, zip NUMBER) RETURN address_t EXTERNAL NAME 'create (java.lang.String, java.lang.String, java.lang.String, int) return Examples.Address', MEMBER FUNCTION to_string RETURN VARCHAR EXTERNAL NAME 'tojava.lang.String() return java.lang.String', MEMBER FUNCTION strip RETURN SELF AS RESULT EXTERNAL NAME 'removeLeadingBlanks () return Examples.Address' ) NOT FINAL; / CREATE OR REPLACE TYPE long_address_t UNDER address_t EXTERNAL NAME 'Examples.LongAddress' LANGUAGE JAVA USING SQLData( street2_attr VARCHAR(250) EXTERNAL NAME 'street2', country_attr VARCHAR (200) EXTERNAL NAME 'country', address_code_attr VARCHAR (50) EXTERNAL NAME 'addrCode', STATIC FUNCTION create_address RETURN long_address_t EXTERNAL NAME 'create() return Examples.LongAddress', STATIC FUNCTION construct (street VARCHAR, city VARCHAR, state VARCHAR, country VARCHAR, addrs_cd VARCHAR) RETURN long_address_t EXTERNAL NAME 'create(java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) return Examples.LongAddress', STATIC FUNCTION construct RETURN long_address_t EXTERNAL NAME 'Examples.LongAddress() return Examples.LongAddress', STATIC FUNCTION create_longaddress ( street VARCHAR, city VARCHAR, state VARCHAR, country VARCHAR, addrs_cd VARCHAR) return long_address_t EXTERNAL NAME 'Examples.LongAddress (java.lang.String, java.lang.String, java.lang.String, java.lang.String, java.lang.String) return Examples.LongAddress', MEMBER FUNCTION get_country RETURN VARCHAR EXTERNAL NAME 'country_with_code () return java.lang.String' ); /
Type Hierarchy Example The following statements create a type hierarchy. Type
employee_t inherits the
ssn attributes from type
person_t and in addition has
salary attributes. Type
part_time_emp_t inherits all of the attributes from
employee_t and, through
employee_t, those of
person_t and in addition has a
num_hrs attribute. Type
part_time_emp_t is final by default, so no further subtypes can be created under it.
CREATE TYPE person_t AS OBJECT (name VARCHAR2(100), ssn NUMBER) NOT FINAL; / CREATE TYPE employee_t UNDER person_t (department_id NUMBER, salary NUMBER) NOT FINAL; / CREATE TYPE part_time_emp_t UNDER employee_t (num_hrs NUMBER); /
You can use type hierarchies to create substitutable tables and tables with substitutable columns.
Varray Type Example The following statement shows how the
phone_list_typ varray type with five elements in the sample
oe schema was created. A hypothetical name is given to the table so that you can duplicate this example in your test database:
CREATE TYPE phone_list_typ_demo AS VARRAY(5) OF VARCHAR2(25);
CREATE TYPE textdoc_typ AS OBJECT ( document_typ VARCHAR2(32) , formatted_doc BLOB ) ; CREATE TYPE textdoc_tab AS TABLE OF textdoc_typ;
Nested Table Type Containing a Varray The following example of multilevel collections is a variation of the sample table
oe.customers. In this example, the
cust_address object column becomes a nested table column with the
phone_list_typ varray column embedded in it. The phone_list_typ type was created in Varray Type Example.
CREATE TYPE cust_address_typ2 AS OBJECT ( street_address VARCHAR2(40) , postal_code VARCHAR2(10) , city VARCHAR2(30) , state_province VARCHAR2(10) , country_id CHAR(2) , phone phone_list_typ_demo ); CREATE TYPE cust_nt_address_typ AS TABLE OF cust_address_typ2;
CREATE TYPE demo_typ1 AS OBJECT (a1 NUMBER, a2 NUMBER); CREATE TABLE demo_tab1 (b1 NUMBER, b2 demo_typ1); INSERT INTO demo_tab1 VALUES (1, demo_typ1(2,3));
See Also:Oracle Database Object-Relational Developer's Guide for more information about constructors
CREATE TYPE demo_typ2 AS OBJECT (a1 NUMBER, MEMBER FUNCTION get_square RETURN NUMBER);
Next a table is created with an object type column and some data is inserted into the table:
CREATE TABLE demo_tab2(col demo_typ2); INSERT INTO demo_tab2 VALUES (demo_typ2(2));
The type body is created to define the member function, and the member method is invoked:
CREATE TYPE BODY demo_typ2 IS MEMBER FUNCTION get_square RETURN NUMBER IS x NUMBER; BEGIN SELECT c.col.a1*c.col.a1 INTO x FROM demo_tab2 c; RETURN (x); END; END; / SELECT t.col.get_square() FROM demo_tab2 t; T.COL.GET_SQUARE() ------------------ 4
Unlike function invocations, method invocations require parentheses, even when the methods do not have additional arguments.
Creating a Static Method: Example The following example changes the definition of the
employee_t type to associate it with the
construct_emp function. The example first creates an object type
department_t and then an object type
employee_t containing an attribute of type
CREATE OR REPLACE TYPE department_t AS OBJECT ( deptno number(10), dname CHAR(30)); CREATE OR REPLACE TYPE employee_t AS OBJECT( empid RAW(16), ename CHAR(31), dept REF department_t, STATIC function construct_emp (name VARCHAR2, dept REF department_t) RETURN employee_t );
This statement requires the following type body statement.
CREATE OR REPLACE TYPE BODY employee_t IS STATIC FUNCTION construct_emp (name varchar2, dept REF department_t) RETURN employee_t IS BEGIN return employee_t(SYS_GUID(),name,dept); END; END;
Next create an object table and insert into the table:
CREATE TABLE emptab OF employee_t; INSERT INTO emptab VALUES (employee_t.construct_emp('John Smith', NULL));
See Also:Oracle Database Object-Relational Developer's Guide for more information about objects, incomplete types, varrays, and nested tables