postgresql function 中的流程控制二(循环)
循环
LOOP循环
[<<label>>]loopstatementsexit [label] [when boolean-expression];end loop [label];
loop 定义一个无条件循环,无限循环,一直到exit,或者return语句的时候终止循环
labal(标签)可由exit 或者continue使用,用于在嵌套循环中声明在那一层进行循环
如果声明了when,循环退出只有在boolean-expression为真的时候,否则控制落在exit后面的语句
案例:
在一个表中循环插入 10 个数。
create or replace function insert_loop_fun()returns void as $$declaren numeric :=0;begindrop table test ;create table test (id numeric);loopn := n+1;insert into test values (n);exit when n>=10;end loop;end;$$ language plpgsql;
结果:
vastbase=# select insert_loop_fun();insert_loop_fun-----------------(1 row)vastbase=# select * from test;id----12345678910(10 rows)
while 循环
while boolean-expression loopstatements;end loop;
只要条件 boolean-expression 为真,while 就会一直在loop中循环,条件每次在循环体中进行检查。
还是上面的案例:
create or replace function insert_while_fun()returns void as $$declaren int := 0;begincreate table test (id int);while n <10 loopn:=n+1;insert into test values(n);end loop;end;$$ language plpgsql;
结果:
vastbase=# select * from test;id----12345678910(10 rows)
for 循环遍历一个数值变量
for name in [reverse] expression .. expression [by expression] loopstatementsend loop [label];
for循环中的数字循环默认是升序的,每次+1,使用reverse 可以实现降序,每次-1。
演示:结合上一章的条件判断,创建一个有输入值的函数,当输入输入一个<10的数字后,从这个数字开始到10 全都输入到new表中,并且,如果输入的值<1或者>10 全都报错。
create or replace function select_for_fun(i numeric)returns setof numeric as $$ --这里要返回一个numeric类型的结果集declarej numeric;res numeric ;beginif i >10 thenraise notice ' input error ';elseif i < 1 thenraise notice ' input error ';elsecreate table new (id int);for j in i .. 10 loopselect j into res ;insert into new values (res);end loop;end if;end;$$ language plpgsql;结果:vastbase=# select select_for_fun(-1);NOTICE: input errorCONTEXT: referenced column: select_for_funselect_for_fun----------------(0 rows)vastbase=# select * from new;ERROR: relation "new" does not exist on vastbaseLINE 1: select * from new;vastbase=# select select_for_fun(11);NOTICE: input errorCONTEXT: referenced column: select_for_funselect_for_fun----------------(0 rows)vastbase=# select * from new;ERROR: relation "new" does not exist on vastbaseLINE 1: select * from new;^vastbase=# select select_for_fun(6);select_for_fun----------------(0 rows)vastbase=# select * from new;id----678910(5 rows)
for 循环遍历命令的结果
for target in query loopstatementsend loop [label];
示例:查出emp表中的人名,职位,工资,将其放到另外一张表的一个字段中。
用到了我们上一篇文章用的emp表,没有那张表去上一个文章找找。
create table t2 (info varchar);create or replace function emp_for_fun()returns void as $$ -- 这里的返回类型也可以是recorddeclarei record ; --record 这个类型是pg独有的,其实这也不是一个数据类型,这个就是一个记录类似行变量的占位符。for i in select ename,job,sal from emp loopinsert into t2 values (i);end loop;end;$$ language plpgsql;
结果:
vastbase=# select emp_for_fun();emp_for_fun-------------(1 row)vastbase=# select * from t2;info------------------------(SMITH,CLERK,800)(ALLEN,SALESMAN,1600)(WARD,SALESMAN,1250)(JONES,MANAGER,2975)(MARTIN,SALESMAN,1250)(BLAKE,MANAGER,2850)(CLARK,MANAGER,2450)(SCOTT,ANALYST,3000)(KING,PRESIDENT,5000)(TURNER,SALESMAN,1500)(ADAMS,CLERK,1100)(JAMES,CLERK,950)(FORD,ANALYST,3000)(MILLER,CLERK,1300)(14 rows)
continue 语句
continue [label] [when boolean-expression];
continue 是在执行过程中只要when boolean-expression为真,则跳过循环,直到when boolean-expression为假,继续后面的循环
continue 就是在做短暂中断循环。
示例:在1到10中不输出5;
create or replace function con_fun()returns void as $$declaren numeric :=0;beginwhile n <10 loopn:=n+1;continue when n=5;raise notice 'n 当前值为:%',n;end loop;end;$$ language plpgsql;
结果
vastbase=# select con_fun();NOTICE: n 当前值为:1CONTEXT: referenced column: con_funNOTICE: n 当前值为:2CONTEXT: referenced column: con_funNOTICE: n 当前值为:3CONTEXT: referenced column: con_funNOTICE: n 当前值为:4CONTEXT: referenced column: con_funNOTICE: n 当前值为:6CONTEXT: referenced column: con_funNOTICE: n 当前值为:7CONTEXT: referenced column: con_funNOTICE: n 当前值为:8CONTEXT: referenced column: con_funNOTICE: n 当前值为:9CONTEXT: referenced column: con_funNOTICE: n 当前值为:10CONTEXT: referenced column: con_funcon_fun---------(1 row)
exit语句
exit [label][when boolean-expression];
exit 是在执行过程中只要when boolean-expression为真,会跳出循环,循环不再进行。
示例:
create or replace function con_fun_eixt()returns void as $$declaren numeric :=0;beginwhile n <10 loopn:=n+1;exit when n=5;raise notice 'n 当前值为:%',n;end loop;end;$$ language plpgsql;
结果:
vastbase=# select con_fun_eixt();NOTICE: n 当前值为:1CONTEXT: referenced column: con_fun_eixtNOTICE: n 当前值为:2CONTEXT: referenced column: con_fun_eixtNOTICE: n 当前值为:3CONTEXT: referenced column: con_fun_eixtNOTICE: n 当前值为:4CONTEXT: referenced column: con_fun_eixtcon_fun_eixt--------------(1 row)
THAT'S ALL
BY CUI PEACE!!!




