ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

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

2022-05-17 12:03:29  阅读:221  来源: 互联网

标签:notice Postgresql name -- value return record postgresql id


初识函数

 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

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有