Declaration

更新时间:
复制 MD 格式

PL/SQL declarations define the variables, constants, aliases, and type references available within a block. This topic covers the declaration syntax and the supported variable kinds.

Variable declarations

All variables used in a block must be declared in the declarations section. Two exceptions apply automatically: the loop variable of a FOR loop over an integer range is declared as an integer, and the loop variable of a FOR loop over a cursor result is declared as a record variable.

PL/SQL variables accept any SQL data type, including INTEGER, VARCHAR, and CHAR.

Sample variable declarations

user_id integer;
quantity numeric(5);
url varchar;
myrow tablename%ROWTYPE;
myfield tablename.columnname%TYPE;
arow RECORD;

Syntax

name [ CONSTANT ] type [ COLLATE collation_name ] [ NOT NULL ] [ { DEFAULT | := | = } expression ];
OptionBehavior
DEFAULT (or := or =)Sets the initial value when the block is entered. If omitted, the variable starts as NULL.
CONSTANTPrevents reassignment after initialization. The value stays fixed for the duration of the block.
COLLATESpecifies the collation for the variable.
NOT NULLCauses a runtime error if NULL is assigned. A non-NULL default value is required.

The equal sign (=) can be used to replace the := operator, which is compatible with PL/SQL.

The default value is evaluated each time the block is entered, not at compile time. For example, assigning now() to a TIMESTAMP variable produces the timestamp at function invocation, not when the function was compiled.

Examples

quantity integer DEFAULT 32;
url      varchar := 'http://mysite.com';
user_id  CONSTANT integer := 10;

Declare function parameters

PL/SQL names function parameters $1, $2, and so on. Declare an alias to make the code more readable. Both the alias and the $n identifier can reference the parameter value.

Name parameters in CREATE FUNCTION (recommended)

Pass the parameter name directly in the CREATE FUNCTION statement. This is the preferred approach because the name can be qualified with the function name (for example, sales_tax.subtotal).

CREATE FUNCTION sales_tax(subtotal real) RETURN real IS
BEGIN
    RETURN subtotal * 0.06;
END;

Declare an explicit alias

Use the ALIAS FOR syntax in the DECLARE section when you need to alias a positional parameter after the fact.

name ALIAS FOR $n;
CREATE FUNCTION sales_tax(real) RETURN real IS
DECLARE
    subtotal ALIAS FOR $1;
BEGIN
    RETURN subtotal * 0.06;
END;
These two forms are not equivalent. In the first form, subtotal can be referenced as sales_tax.subtotal. In the second form it cannot — but you can attach a label to the inner block and qualify subtotal with that label instead.

Example with multiple aliases

CREATE FUNCTION instr(varchar, integer) RETURN integer IS
DECLARE
    v_string ALIAS FOR $1;
    index    ALIAS FOR $2;
BEGIN
    -- Compute by using v_string and index.
END;

Example with a composite-type parameter

CREATE FUNCTION concat_selected_fields(in_t sometablename) RETURN text IS
BEGIN
    RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7;
END;

Output parameters

Output parameters (OUT) work like regular parameters: assign values to them during execution, and their final values become the function's return value. The RETURNS real clause is redundant when OUT is used and can be omitted.

CREATE FUNCTION sales_tax(subtotal real, OUT tax real) IS
BEGIN
    tax := subtotal * 0.06;
END;

Output parameters are the standard way to return multiple values:

CREATE FUNCTION sum_n_product(x int, y int, OUT sum int, OUT prod int) IS
BEGIN
    sum  := x + y;
    prod := x * y;
END;

When multiple OUT parameters are used, PolarDB creates an anonymous record type for the result. Include RETURNS record if you want to write an explicit RETURNS clause.

RETURNS TABLE

RETURNS TABLE is equivalent to declaring one or more OUT parameters with RETURNS SETOF sometype.

CREATE FUNCTION extended_sales(p_itemno int)
RETURN TABLE(quantity int, total numeric) IS
BEGIN
    RETURN QUERY SELECT s.quantity, s.quantity * s.price FROM sales AS s
                 WHERE s.itemno = p_itemno;
END;

Polymorphic return types

When a function has a polymorphic return type, PolarDB creates a special $0 parameter whose data type matches the return type deduced from the inputs. $0 is initialized to NULL and cannot be modified. You can create an alias for $0. For example, the following function can be used on any data type that supports the + operator:

CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
RETURN anyelement IS
DECLARE
    result ALIAS FOR $0;
BEGIN
    result := v1 + v2 + v3;
    RETURN result;
END;

Use the anycompatible family of types so that input parameters are automatically promoted to a common type:

CREATE FUNCTION add_three_values(v1 anycompatible, v2 anycompatible, v3 anycompatible)
RETURN anycompatible IS
BEGIN
    RETURN v1 + v2 + v3;
END;

This invocation is valid — the integer inputs are automatically promoted to numeric:

SELECT add_three_values(1, 2, 4.7);

With anyelement, inputs must be converted to the same type manually. Use anycompatible to avoid this.

You can achieve the same result using polymorphic OUT parameters instead of $0:

CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement,
                                 OUT sum anyelement)
IS
BEGIN
    sum := v1 + v2 + v3;
END;

Declare aliases

newname ALIAS FOR oldname;

The ALIAS FOR syntax works for any variable, not just function parameters. Its primary use is renaming predetermined names such as NEW or OLD in trigger functions.

DECLARE
    prior   ALIAS FOR old;
    updated ALIAS FOR new;

Avoid using ALIAS FOR in an unrestricted way — aliasing the same object under multiple names leads to confusion. Limit its use to overriding predetermined names.

Copy types (%TYPE)

variable%TYPE

%TYPE borrows the data type of a variable or table column. Use it to declare variables that hold database values without hard-coding the data type.

user_id users.user_id%TYPE;

If the referenced column's type changes later, the function definition requires no update. %TYPE is especially useful in polymorphic functions, where the data type of an internal variable may differ between invocations.

Use row types (%ROWTYPE)

name table_name%ROWTYPE;
name composite_type_name;

A row variable holds a complete row from a SELECT or FOR query result, provided the column set matches the declared type. Access individual fields using dot notation: rowvar.field.

Each table has an associated composite type with the same name, so specifying %ROWTYPE is optional in PolarDB. Use it anyway — it makes the code portable across databases.

Function parameters can be composite types representing complete table rows. In that case, the $n identifier is a row variable and its fields are accessible as $1.user_id.

Example

CREATE FUNCTION merge_fields(t_row table1) RETURN text IS
DECLARE
    t2_row table2%ROWTYPE;
BEGIN
    SELECT * INTO t2_row FROM table2 WHERE ... ;
    RETURN t_row.f1 || t2_row.f3 || t_row.f5 || t_row.f7;
END;

SELECT merge_fields(t.*) FROM table1 t WHERE ... ;

Use record types (RECORD)

name RECORD;

Record variables are similar to row variables but have no predefined structure. The structure is set by the first SELECT or FOR assignment and can change with each subsequent assignment. Accessing a field before any value is assigned causes a runtime error.

RECORD is a placeholder, not a true data type. A function declared with return type record is different from a record variable — when the function is called and parsed, its row structure is determined and fixed. A record variable's structure can change at any time.

Collate PL/SQL variables

When a function has parameters of collatable data types, PolarDB identifies a collation per invocation based on the collations of the actual arguments. If no implicit collation conflict exists, that collation is applied to all collatable parameters and local variables automatically.

CREATE FUNCTION less_than(a text, b text) RETURN boolean IS
BEGIN
    RETURN a < b;
END;

-- Uses the common collation of text_field_1 and text_field_2:
SELECT less_than(text_field_1, text_field_2) FROM table1;

-- Uses the C collation:
SELECT less_than(text_field_1, text_field_2 COLLATE "C") FROM table1;

Because the identified collation also applies to local variables, the following function behaves identically to the one above:

CREATE FUNCTION less_than(a text, b text) RETURN boolean IS
DECLARE
    local_a text := a;
    local_b text := b;
BEGIN
    RETURN local_a < local_b;
END;

If no parameters have a collatable type, or if no common collation can be identified, variables use the default collation of their data type (usually the database default). Variables of domain types may have different defaults.

Override the collation in a declaration

DECLARE
    local_a text COLLATE "en_US";

Override the collation in an expression

CREATE FUNCTION less_than_c(a text, b text) RETURN boolean IS
BEGIN
    RETURN a < b COLLATE "C";
END;

An explicit COLLATE clause overrides all collations associated with columns, parameters, and local variables in the expression — the same behavior as in plain SQL.