所有在块里使用的变量都必须在块的声明段里先进行声明,唯一的例外是FOR循环里的循环计数变量, 该变量被自动声明为整型。变量声明的语法如下: variable_name [ CONSTANT ] variable_type [ NOT NULL ] [ { DEFAULT | := } expression ];
RAISE NOTICE 'Quantity here is %', quantity; quantity := 50;
-- 创建一个子块 -- DECLARE
代码语言:javascript复制 quantity integer := 80;
BEGIN
代码语言:javascript复制 RAISE NOTICE 'Quantity here is %', quantity;
END; RAISE NOTICE 'Quantity here is %', quantity; RETURN quantity; END; $$ LANGUAGE plpgsql; #执行该函数以进一步观察其执行的结果。 postgres=# select somefunc(); NOTICE: Quantity here is 30 NOTICE: Quantity here is 80 NOTICE: Quantity here is 50
somefunc
50 (1 row)--在这里的数量是30--在这里的数量是80--在这里的数量是50 1). SQL中的数据类型均可作为PL/pgSQL变量的数据类型,如integer、varchar和char等。2). 如果给出了DEFAULT子句,该变量在进入BEGIN块时将被初始化为该缺省值,否则被初始化为SQL空 值。缺省值是在每次进入该块时进行计算的。因此,如果把now()赋予一个类型为timestamp的变量,那 么该变量的缺省值将为函数实际调用时的时间,而不是函数预编译时的时间。3). CONSTANT选项是为了避免该变量在进入BEGIN块后被重新赋值,以保证该变量为常量。4). 如果声明了NOT NULL,那么赋予NULL数值给该变量将导致一个运行时错误。因此所有声明为NOT NULL的变量也必须在声明时定义一个非空的缺省值。1. 函数参数的别名:传递给函数的参数都是用1、2这样的标识符来表示的。为了增加可读性,我们可以为其声明别名。之 后别名和数字标识符均可指向该参数值,见如下示例:1). 在函数声明的同时给出参数变量名。 CREATE FUNCTION sales_tax(subtotal real) RETURNS real AS
代码语言:javascript复制BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;
2). 在声明段中为参数变量定义别名。 CREATE FUNCTION sales_tax(REAL) RETURNS real AS $$
代码语言:javascript复制DECLARE
subtotal ALIAS FOR $1;
BEGIN
RETURN subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;
3). 对于输出参数而言,我们仍然可以遵守1)和2)中的规则。 CREATE FUNCTION sales_tax(subtotal real, OUT tax real) AS $$
代码语言:javascript复制BEGIN
tax := subtotal * 0.06;
END;
$$ LANGUAGE plpgsql;
4). 如果PL/pgSQL函数的返回类型为多态类型(anyelement或anyarray),那么函数就会创建一个特殊的 参数:$0。我们仍然可以为该变量设置别名。 CREATE FUNCTION add_three_values(v1 anyelement, v2 anyelement, v3 anyelement)
代码语言:javascript复制RETURNS anyelement AS $$
DECLARE
result ALIAS FOR $0;
BEGIN
result := v1 v2 v3;
RETURN result;
END;
$$ LANGUAGE plpgsql;
2. 拷贝类型: 见如下形式的变量声明: %TYPE表示一个变量或表字段的数据类型,PL/pgSQL允许通过该方式声明一个变量,其类型等同于 variable或表字段的数据类型,见如下示例: 在上面的例子中,变量user_id的数据类型等同于users表中user_id字段的类型。 通过使用%TYPE,一旦引用的变量类型今后发生改变,我们也无需修改该变量的类型声明。最后需要说 明的是,我们可以在函数的参数和返回值中使用该方式的类型声明。 3. 行类型: 见如下形式的变量声明: table_name%ROWTYPE表示指定表的行类型,我们在创建一个表的时候,PostgreSQL也会随之创建出 一个与之相应的复合类型,该类型名等同于表名,因此,我们可以通过以上两种方式来声明行类型的变 量。由此方式声明的变量,可以保存SELECT返回结果中的一行。如果要访问变量中的某个域字段,可以 使用点表示法,如rowvar.field,但是行类型的变量只能访问自定义字段,无法访问系统提供的隐含字 段,如OID等。对于函数的参数,我们只能使用复合类型标识变量的数据类型。最后需要说明的是,推 荐使用%ROWTYPE的声明方式,这样可以具有更好的可移植性,因为在Oracle的PL/SQL中也存在相同 的概念,其声明方式也为%ROWTYPE。见如下示例: variable%TYPE user_id users.user_id%TYPE; name table_name%ROWTYPE;
代码语言:javascript复制name composite_type_name;
4. 记录类型: 见如下形式的变量声明: 记录变量类似于行类型变量,但是它们没有预定义的结构,只能通过SELECT或FOR命令来获取实际的行 结构,因此记录变量在被初始化之前无法访问,否则将引发运行时错误。 注:RECORD不是真正的数据类型,只是一个占位符。