%TYPE anchors a variable's data type to a table column or another variable. When the referenced column or variable changes type, the anchored variable automatically picks up the new type — no declaration update needed.
%TYPE works in both variable declarations and formal parameter declarations.Syntax
name { { table | view }.column | variable }%TYPE;-- v_name inherits the data type of the emp.ename column
v_name emp.ename%TYPE;Parameters
| Parameter | Description |
|---|---|
name | The identifier assigned to the variable, or the formal parameter being declared |
column | A column in a table or view |
variable | A variable declared prior to the variable identified by name |
Inheritance rules
The item declared with %TYPE is the referencing item. The column or variable it references is the referenced item.
In both cases — whether the referenced item is a table column or a previously declared variable — the referencing item inherits the data type of the referenced item. It does not inherit the NOT NULL constraint, the DEFAULT clause, or the := initial value.
Example: define parameters and variables using %TYPE
The following procedure queries the emp table by employee number, retrieves the employee's details, and compares the employee's salary against the department average.
Version 1 — explicit data types:
CREATE OR REPLACE PROCEDURE emp_sal_query (
p_empno IN NUMBER
)
IS
v_ename VARCHAR2(10);
v_job VARCHAR2(9);
v_hiredate DATE;
v_sal NUMBER(7,2);
v_deptno NUMBER(2);
v_avgsal NUMBER(7,2);
BEGIN
SELECT ename, job, hiredate, sal, deptno
INTO v_ename, v_job, v_hiredate, v_sal, v_deptno
FROM emp WHERE empno = p_empno;
DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);
DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Dept # : ' || v_deptno);
SELECT AVG(sal) INTO v_avgsal
FROM emp WHERE deptno = v_deptno;
IF v_sal > v_avgsal THEN
DBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the '
|| 'department average of ' || v_avgsal);
ELSE
DBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the '
|| 'department average of ' || v_avgsal);
END IF;
END;Version 2 — with %TYPE:
All variable and parameter declarations use %TYPE to anchor types to the emp table, eliminating hardcoded data types from the declaration block.
CREATE OR REPLACE PROCEDURE emp_sal_query (
p_empno IN emp.empno%TYPE
)
IS
v_ename emp.ename%TYPE;
v_job emp.job%TYPE;
v_hiredate emp.hiredate%TYPE;
v_sal emp.sal%TYPE;
v_deptno emp.deptno%TYPE;
v_avgsal v_sal%TYPE;
BEGIN
SELECT ename, job, hiredate, sal, deptno
INTO v_ename, v_job, v_hiredate, v_sal, v_deptno
FROM emp WHERE empno = p_empno;
DBMS_OUTPUT.PUT_LINE('Employee # : ' || p_empno);
DBMS_OUTPUT.PUT_LINE('Name : ' || v_ename);
DBMS_OUTPUT.PUT_LINE('Job : ' || v_job);
DBMS_OUTPUT.PUT_LINE('Hire Date : ' || v_hiredate);
DBMS_OUTPUT.PUT_LINE('Salary : ' || v_sal);
DBMS_OUTPUT.PUT_LINE('Dept # : ' || v_deptno);
SELECT AVG(sal) INTO v_avgsal
FROM emp WHERE deptno = v_deptno;
IF v_sal > v_avgsal THEN
DBMS_OUTPUT.PUT_LINE('Employee''s salary is more than the '
|| 'department average of ' || v_avgsal);
ELSE
DBMS_OUTPUT.PUT_LINE('Employee''s salary does not exceed the '
|| 'department average of ' || v_avgsal);
END IF;
END;Note two patterns in version 2:
p_empno IN emp.empno%TYPE— a formal parameter anchored to a table column using%TYPEv_avgsal v_sal%TYPE— a variable anchored to another variable (not a table column)
Sample output:
EXEC emp_sal_query(7698);
Employee # : 7698
Name : BLAKE
Job : MANAGER
Hire Date : 01-MAY-81 00:00:00
Salary : 2850.00
Dept # : 30
Employee's salary is more than the department average of 1566.67