%ROWTYPE and %TYPE
On this page
The %ROWTYPE
attribute designates a record type that represents a table row and the %TYPE
attribute designates the type of a referenced scalar object, such as another variable or column.
This can make it easier to program stored procedures and anonymous code blocks because you don't have to write as much code.
Syntax
%ROWTYPE attribute:
variable_name \table_name%ROWTYPEvariable_name QUERY LIKE table_name%ROWTYPE
%TYPE attribute:
variable_name {other_variable_name | table_name.column_name}%TYPE
Remarks
-
%ROWTYPE
can be used with tables, views, and query objects. -
User-Defined Functions (UDFs), Stored Procedures (SPs), and anonymous code blocks using
%ROWTYPE
and/or%TYPE
attributes are associated with specific tables.Any alterations of an associated table's schema trigger a recompilation of the UDF, SP, or anonymous code block upon the next execution. The %ROWTYPE
and%TYPE
attributes are defined during the initial function compilation.So altering the table during function or anonymous code block execution does not impact the variable, parameter, or return types; altered types will take effect on the next execution.
Examples
Shortening Code that Processes Wide Tables
In the following example, the data type of qry
needs to be declared before it is assigned.table1
, which qry
represents, must be specified.
CREATE TABLE table1 (id INT, name TEXT);INSERT INTO table1 VALUES (1, 'red'), (2, 'green'), (3, 'blue');
CREATE TABLE output_log(msg TEXT);
DELIMITER //CREATE OR REPLACE PROCEDURE p() ASDECLAREqry QUERY(id INT, name TEXT) = SELECT id, name FROM table1;arr ARRAY(RECORD(id INT, name TEXT));BEGINarr = COLLECT(qry);FOR x in arr LOOPINSERT INTO output_log VALUES(CONCAT('[', x.id, ', ', x.name, ']'));END LOOP;END //DELIMITER ;
If table1
had hundreds of columns instead of 2, it would be tedious to have to list all of those columns along with their data type.%ROWTYPE
attribute can be used so all the columns don't have to be listed out when defining the QUERY
and ARRAY
data types.
DELIMITER //CREATE OR REPLACE PROCEDURE p() ASDECLAREqry QUERY LIKE table1%ROWTYPE;arr ARRAY(table1%ROWTYPE);BEGINqry = SELECT * FROM table1;arr = COLLECT(qry);FOR x in arr LOOPEND LOOP;END //DELIMITER ;
Allowing Anonymous Code Block or SP to Adapt to Schema Changes
CREATE TABLE IF NOT EXISTS test(a INT, b VARCHAR(255));
INSERT test VALUES (1,'red'),(2,'green');
CREATE VIEW testv AS SELECT a, b FROM test;
SELECT * FROM test;
+---+-------+
| a | b |
+---+-------+
| 1 | red |
| 2 | green |
+---+-------+
DELIMITER //DODECLAREqry QUERY LIKE testv%ROWTYPE;arr ARRAY(qry%ROWTYPE);r test%ROWTYPE;tot test.a%TYPE;BEGINqry = SELECT * FROM test ORDER BY a DESC;arr = COLLECT(qry);r = arr[0];ECHO SELECT r.a, r.b;SELECT SUM(a) INTO tot FROM test;ECHO SELECT tot;END //DELIMITER ;
+-----+
| tot |
+-----+
| 3 |
+-----+
ALTER TABLE test ADD COLUMN c NUMERIC(18,2);UPDATE test SET c = a;ALTER TABLE test DROP COLUMN a;ALTER TABLE test CHANGE c a;
The view must be recreated because the order of the columns in test
has changed.%ROWTYPE
depends on column order.
DROP VIEW testv;CREATE VIEW testv AS SELECT * FROM test;
Rerun the anonymous code block above and it will pick up the new type.
DELIMITER //DODECLAREqry QUERY LIKE testv%ROWTYPE;arr ARRAY(qry%ROWTYPE);r test%ROWTYPE;tot test.a%TYPE;BEGINqry = SELECT * FROM test ORDER BY a DESC;arr = COLLECT(qry);r = arr[0];ECHO SELECT r.a, r.b;SELECT SUM(a) INTO tot FROM test;ECHO SELECT tot;END //DELIMITER ;
+------+
| tot |
+------+
| 3.00 |
+------+
Allowing UDFs to Adapt to Table Column Type Changes
Consider a gaming application where a function performs logic on a points
table to update users' points:
CREATE TABLE points(id INT, result INT);
This UDF code can adapt to changes in the types of columns of the points table.b
also illustrates how a variable type can be declared as the same type as another variable in the same function.
DELIMITER //CREATE OR REPLACE FUNCTION update_pts(v points.result%TYPE) returns points.result%TYPE ASDECLAREr INT;b r%TYPE;result points.result%TYPE = 0;BEGIN-- You can perform any additional logic here --RETURN result;END//DELIMITER ;
SELECT update_pts(1);
+---------------+
| update_pts(1) |
+---------------+
| 0 |
+---------------+
In summary, %ROWTYPE
and %TYPE
allow several ways to shorten your code and make it adapt to schema changes automatically.
Last modified: March 8, 2024