数据库
首页 > 数据库> > PL/pgSQL编写postgresql函数(一)--声明语法(转darion@Postgresql)仅做学习使用

PL/pgSQL编写postgresql函数(一)--声明语法(转darion@Postgresql)仅做学习使用

作者:互联网

初识函数

 1 create or replace function somefunc() returns integer as
 2 
 3 $$
 4 
 5 declare
 6 
 7 quantity integer := 30;
 8 
 9 begin
10 
11 raise notice 'Quantity1 here is %',quantity;
12 
13 quantity := 50;
14 
15 --创建一个子块
16 
17 declare
18 
19 quantity integer := 80;
20 
21 begin
22 
23 raise notice 'Quantity2 here is %',quantity;
24 
25 end;
26 
27 raise notice 'Quantity3 here is %',quantity;
28 
29 return quantity;
30 
31 end
32 
33 $$
34 
35 language plpgsql

思考:raise notice依次打印出什么结果????

 

结果:

NOTICE: 00000: Quantity1 here is 30

NOTICE: 00000: Quantity2 here is 80

NOTICE: 00000: Quantity3 here is 50  

1、声明语法

1.1、函数声明语法
1.1.1 结构定义
CREATE [ OR REPLACE ] FUNCTION funcname([IN parameters,OUT parameters]) RETURNS return_value_type AS

$body$

DECLARE

declaration;

[...]

BEGIN

statement --逻辑块(pl/pgsql代码块)

[ RETURN return_value;]

END;

$body$

LANGUAGE plpgsql

1.1.2 关键字说明
CREATE [ OR REPLACE ] FUNCTION 创建函数关键字

IN 表示该参数为输入参数

OUT 表示该参数为输出参数

DECLARE 定义变量列表

BEGIN 正文代码开始

RETURN 返回值关键字

END 正文代码结束

LANGUAGE 指定编程语言

1.1.3参数说明
funcname 函数名

parameters为参数(由 参数名 类型组成,如v_id int)

declaration 函数变量列表(变量名 类型)

return_value_type 返回值类型(无返回值使用void)

$body$ 表示里面引用的内容是函数逻辑块

return_value 返回值变量

注意:

A. 输入参数可以有多个,输出参数也可以为多个。

B. 函数参数中使用OUT标明返回参数或者return_value_type为void时,函数逻辑块中不需要使用return进行值返回,如果没有使用OUT且return_value_type不为void时,必须在逻辑块中使用return表明返回值,无可写成return null。

C. OUT指定的返回值类型或者return指定的返回值类型必须与returns后指定的类型一致。

例子:

1 create table t_test(id serial,name varchar,age int,code text);
2 
3 insert into t_test(name,age,code) values('张三',18,'10010-11'),
4 
5 ('李四',20,'10010-12'),
6 
7 ('王五',22,'10010-13');

 

函数:

 1 create or replace function t_func(in v_id int,out v_name varchar)
 2 
 3 returns varchar as
 4 
 5 $$
 6 
 7 begin
 8 
 9 select name into $2 from t_test where id=$1;
10 
11 end
12 
13 $$
14 
15 language plpgsql

如上函数也可改写为:

create or replace function t_func( v_id int)

returns varchar as

$$

declare

v_name varchar;

begin

select name into v_name from t_test where id=$1;

return v_name;

end

$$

language plpgsql

 

函数参数没有使用IN 或者 OUT表名时,缺省为输入参数。

1.2、参数传递与别名
在postgresql函数中,传递给函数的参数被命名为$1、$2等等。为了增强$n的可读性,我们可以为参数声明别名。

我们可以通过两中方式来声明参数别名(显式声明与隐式声明),不同的定义方法,参数的调用方法也不一样。

当然,无论是显式声明还是隐式声明,都可以通过使用$n来进行参数传递,如上述函数例子中的$1。

1.2.1、显式声明
显示声明就是在CREATE FUNCTION 命令中为参数给定一个名称,例如

create function fn_test1(total int) returns int as

$$

begin

return total * 2;

end

$$

language plpgsql;

 

如上,为输入参数给定名称为total,在函数中可以直接使用total来调用该参数进行运算。当然此处也可以将total*2编写成$1*2。

 

​​​​​​​1.2.2、隐士声明
我们可以通过在函数declare块中使用 name ALIAS FOR $n 来为参数声明别名,关键字为ALIAS FOR。如下

create function fn_test2( int) returns int as

$$

declare

subtotal ALIAS FOR $1;

begin

return subtotal * 2;

end

$$

language plpgsql;

 

​​​​​​​1.3、变量/常量声明

1.3.1 语法
函数中在declare块中声明变量语法为

variable_name [ CONSTANT ] data_type [ NOT NULL ] [ { DEFAULT | := } value ] ;

其中:

variable_name 为变量/常量名称

CONSTANT 关键字标识为常量(值不可修改)

data_type 变量/常量类型

NOT NULL 约束该变量/常量初始值不能为空(声明时就需要有default值)

DEFAULT 设置默认值

:= 赋值运算符(设置默认值)

例子如下:

 1 create or replace function fn_test4() returns void as
 2 
 3 $$
 4 
 5 declare
 6 
 7 v_value1 varchar;
 8 
 9 v_value2 int:= 100 ;
10 
11 v_value3 varchar default '瀚高3';
12 
13 v_value4 varchar not null := '瀚高4' ;
14 
15 v_value5 varchar not null default '瀚高5' ;
16 
17 begin
18 
19 raise notice 'v_value1=%',v_value1;
20 
21 raise notice 'v_value2=%',v_value2;
22 
23 raise notice 'v_value3=%',v_value3;
24 
25 raise notice 'v_value4=%',v_value4;
26 
27 raise notice 'v_value5=%',v_value5;
28 
29 end
30 
31 $$
32 
33 language plpgsql

 

执行打印结果:

test_db=# select fn_test4();

NOTICE: 00000: v_value1=<NULL>

NOTICE: 00000: v_value2=100

NOTICE: 00000: v_value3=瀚高3

NOTICE: 00000: v_value4=瀚高4

NOTICE: 00000: v_value5=瀚高5

fn_test4

----------

(1 行记录)

1.3.2 错误示例
如下属于错误定义

有not null约束无默认值,且没有给该变量赋值

 

创建函数不会报错,但调用时会报错误。

注意:not null,千万不要写成notnull,否则会当成判断语句执行,出现如下效果:

create or replace function fn_test4() returns void as

$$

declare

v_value varchar :='张三' notnull;

begin

raise notice 'v_value=%',v_value;

end

$$

language plpgsql

 

test_db=# select fn_test4();

NOTICE: 00000: v_value=true

fn_test4

----------

(1 行记录)

可以看到打印出来的v_value值为true,但我们明明给v_value赋值为“张三”。由于解析器当成判断语句执行,所以当v_value有初始值,判断出v_value的值不为null时,结果为true。

1.4、其他声明语法
​​​​​​​1.4.1、拷贝类型
将变量类型声明为数据库中已有列数据类型。

声明语法 v_value variable%TYPE

例子 v_user_id user.user_id%TYPE 将v_user_id变量数据类型声明为user表中user_id的数据类型。

create or replace function fn_type(v_id int) returns int as

$$

declare

v_user_id t_test.id%type;

begin

select id from t_test where id=v_id into v_user_id;

return v_user_id;

end

$$

language plpgsql

 

使用拷贝类型的好处是,在多态函数中不需要知道实际引用的数据结构,如果引用项被改变,不需要改变函数定义。

​​​​​​​1.4.2、行类型
一个组合类型的变量称为一个行变量。通常用来接收select或for查询结果的一个整行。

声明语法 v_value table_name%ROWTYPE

v_value composite_type_name;

例子:

 1 create type v_user as (id int,name varchar,code text); --定义一个组合类型
 2 
 3 create or replace function fn_rowtype(v_id int) returns text as
 4 
 5 $$
 6 
 7 declare
 8 
 9 v_user1 t_test%ROWTYPE; --定义为表行数据类型
10 
11 v_user2 v_user; --定义为已有组合类型
12 
13 begin
14 
15 select id,name,age into v_user1 from t_test where id=v_id ;
16 
17 select id,name,code into v_user2 from t_test where id=v_id ;
18 
19 raise notice 'v_user1=%',v_user1;
20 
21 raise notice 'v_user2=%',v_user2;
22 
23 return v_user1.id || v_user1.name ||v_user1.age||'--------'||v_user2.id || v_user2.name ||v_user2.code;
24 
25 end
26 
27 $$
28 
29 language plpgsql

 

1.4.3、记录类型
记录类型和行类型类似,但行累心各有预定义结构,但记录类型没有预定义结构,它是根据select或for命令期间为其赋值的行的真实结构。

记录类型RECORD并非一个真实数据类型,它是一个占位符,随着赋值的行结构动态变化。

声明语法 v_value RECORD

例子

 1 create or replace function fn_record(v_id int) returns text as
 2 
 3 $$
 4 
 5 declare
 6 
 7 v_record RECORD;
 8 
 9  
10 
11 begin
12 
13 select id,name,age into v_record from t_test where id=v_id ;
14 
15 raise notice 'v_record=%',v_record; --1号位
16 
17 select id,name,code into v_record from t_test where id=v_id ;
18 
19 raise notice 'v_record=%',v_record; --2号位
20 
21 return v_record.id ||v_record.name;
22 
23 end
24 
25 $$
26 
27 language plpgsql

 

我们可以看到打印结果如下,可以看到v_record 是变化的。

test_db=# select fn_record(1);

NOTICE: 00000: v_record=(1,张三,18) --1号位

NOTICE: 00000: v_record=(1,张三,10010-11) --2号位

fn_record

-----------

1张三

(1 行记录)
————————————————
版权声明:本文为CSDN博主「darion@Postgresql」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_39727113/article/details/103386428

标签:notice,Postgresql,name,--,value,return,record,postgresql,id
来源: https://www.cnblogs.com/Thenext/p/16280229.html