PostgreSQL-PL/pgSQL控制结构
PL/pgSQL的控制结构是最重要及最有用的一部分了,在实际工作场景都离不开业务处理逻辑,在写PL/pgSQL时,利用控制结构来操作数据。PL/pgSQL支持的控制结构与其他语言几乎差不多,比如:条件、循环、异常等,下面就分别介绍控制结构的使用。
1、条件
对于条件控制结构,支持IF与CASE两种,IF语句有如下三种写法:
if ... then ... end if
if ... then ... else ... end if
if ... then ... elsif ... then ... else ... end if
以及CASE有两种写法:
case ... when ... then ... else ... end case
case when ... then ... else ... end case
1.1、IF-THEN
IF 条件表达式 THEN
主体部分
END IF
IF-THEN是IF结构最简单的形式,如果条件为true,则执行主体部分的脚本,否则不执行。例如:
IF id = 1 THEN
update t_order set order_code = '123' where id = 1;
END IF;
1.2、IF-THEN-ELSE
IF 条件表达式 THEN
主体部分
ELSE
主体部分
END IF;
IF-THEN-ELSE语句在IF-THEN增加了条件表达式为false时,执行ELSE部分的脚本。例如:
IF i_name is not null THEN
select account into r_account from t_user t where t.name = i_name ;
ELSE
raise notice '用户名为空';
END IF;
1.3、IF-THEN-ELSIF
IF 条件表达式 THEN
主体部分
ELSIF 条件表达式 THEN
主体部分
ELSE
主体部分
END IF;
IF-THEN-ELSIF支持多个条件,比如第一个条件不满足,进入第二个条件,否则执行ELSE部分,当然ELSE部分可以不写。
IF i_n < 13 THEN
raise notice '小学';
ELSIF i_n >= 13 and i_n <16 THEN
raise notice '初中';
ELSE
raise notice '完了';
END IF;
1.4、CASE
控制结构的CASE与SQL语句里面的CASE写法一样,例如:
CASE 搜索参数
WHEN 值 THEN 主体部分
ELSE 主体部分
END CASE;
或者
CASE
WHEN 条件表达式 THEN 主体部分
ELSE 主体部分
END CASE;
第一种写法,如果搜索参数在给定的值里面,则执行THEN后面语句,否则执行ELSE部分,ELSE部分可以省略。
第二章写法,符合条件表达式执行THEN后面语句,否则执行ELSE部分。例如:
CASE account
WHEN 'zhangsan','lisi' THEN
msg := '账号为zhangsan或lisi'
ELSE
msg := '未找到账号'
END CASE;
或
CASE
WHEN account in ('zhangsan','lisi') THEN
msg := '账号为zhangsan或lisi'
ELSE
msg := '未找到账号'
END CASE;
CASE语句的作用完全与IF-THEN-ELSIF作用一致。
2、循环
在PL/pgSQL中可以用LOOP、FOR、WHILE实现循环,EXIT与CONTINUE控制循环。
2.1、简单循环
[<
直接使用LOOP定义循环,作用就是无条件的循环,如果这样定义,执行这个语句就进入无限循环,除非在主体里面写EXIT与RETURN,才能终止循环。在实际场景这种不加条件的循环很少会用到。这里的label可选,如果加了label,可以由EXIT与CONTINUE语句使用,比如嵌套循环,最里层循环想直接跳到最外层定义的label就可以使用EXIT label跳到指定的label位置。
2.1.1 、EXIT
EXIT [label] [WHEN 条件表达式]
EXIT后面有两可选部分,给出label部分,则退出到指定的label,如果没指定,则退出当前循环,WHEN部分,则表示符合条件表达式,才退出。
2.1.2、CONTINUE
CONTINUE [label] [WHEN 条件表达式]
CONTINUE的语法与EXIT类似,后面跟的两部分作用也一样,唯一的差别就是EXIT退出循环,CONTINUE是退出本次循环进入下一次循环。
2.2 、FOR循环
2.2.1、简单循环
[<
这种形式的FOR对一定范围的整数进行迭代的循环。 变量name会自动定义为BY类型并且只在循环里存在 (任何该变量名的现存定义在此循环内都将被忽略)。 给出范围上下界的两个表达式在进入循环的时候计算一次。 BY子句指定迭代步长(缺省为 1), 但如果声明了REVERSE步长将变为相应的负值。
--循环输出1..10
for i in 1..10 loop
raise notice '%',i;
end loop;
--从10..1输出,这时就需要加上reverse
for i in reverse 10..1 loop
raise notice '%',i;
end loop;
--从1..10,每隔两个输出
for i in 1..10 by 2 loop
raise notice '%',i;
end loop;
2.2.2、循环查询结果
循环查询结果,在实际场景使用得更多,语法如下:
[<
target是一个记录变量,必须在declare部分先声明,比如声明用户信息:us_info record,完整案例如下:
do $$
declare
t_o record;
begin
for t_o in (select * from t_order) loop
raise notice 'ID:%,客户:%',t_o.id,t_o.cus_name;
end loop;
end $$;
2.3、WHILE循环
[<
while循环,只要符合条件表达式,就会一直循环,例如:
do $$
declare
i int := 10;
begin
while i != 0 loop
raise notice '%',i;
i := i-1;
end loop;
end $$;
3、异常
任何程序都不可能不出错,然而有时我们需要捕获异常继续处理或更好的将异常信息提示给用户,PL/pgSQL异常结构如下:
[<
只要出现异常,就会进入exception部分,然后被识别到对于的when中,比如:
do $$
declare
x int:=6;
begin
x := x/0;
exception
when division_by_zero then
raise notice '除数不能为0';
end $$;