暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

postgresql function 中的流程控制二(循环)

最帅dba工作笔记 2021-05-10
2232

postgresql function 中的流程控制二(循环)


循环


LOOP循环

    [<<label>>]
    loop
    statements
    exit [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 $$
      declare
      n numeric :=0;
      begin
      drop table test ;
      create table test (id numeric);
      loop
      n := 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
        ----
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        (10 rows)
        复制

        while 循环

          while boolean-expression loop
          statements;
          end loop;
          复制

          只要条件 boolean-expression 为真,while 就会一直在loop中循环,条件每次在循环体中进行检查。

          还是上面的案例:

            create or replace function insert_while_fun()
            returns void as $$
            declare
            n int := 0;
            begin
            create table test (id int);
            while n <10 loop
            n:=n+1;
            insert into test values(n);
            end loop;
            end;
            $$ language plpgsql;
            复制

            结果:

              vastbase=# select * from test;
              id
              ----
              1
              2
              3
              4
              5
              6
              7
              8
              9
              10
              (10 rows)
              复制


              for 循环遍历一个数值变量

                for name in [reverse] expression .. expression [by expression] loop 
                statements
                end 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类型的结果集
                  declare
                  j numeric;
                  res numeric ;
                  begin
                  if i >10 then
                  raise notice ' input error ';
                  elseif i < 1 then
                  raise notice ' input error ';
                  else
                  create table new (id int);
                  for j in i .. 10 loop
                  select j into res ;
                  insert into new values (res);
                  end loop;
                  end if;
                  end;
                  $$ language plpgsql;
                  结果:
                  vastbase=# select select_for_fun(-1);
                  NOTICE: input error
                  CONTEXT: referenced column: select_for_fun
                  select_for_fun
                  ----------------
                  (0 rows)
                  vastbase=# select * from new;
                  ERROR: relation "new" does not exist on vastbase
                  LINE 1: select * from new;
                  vastbase=# select select_for_fun(11);
                  NOTICE: input error
                  CONTEXT: referenced column: select_for_fun
                  select_for_fun
                  ----------------
                  (0 rows)
                  vastbase=# select * from new;
                  ERROR: relation "new" does not exist on vastbase
                  LINE 1: select * from new;
                  ^
                  vastbase=# select select_for_fun(6);
                  select_for_fun
                  ----------------
                  (0 rows)
                  vastbase=# select * from new;
                  id
                  ----
                  6
                  7
                  8
                  9
                  10
                  (5 rows)
                  复制


                  for 循环遍历命令的结果

                    for target in query loop 
                    statements
                    end loop [label];
                    复制

                    示例:查出emp表中的人名,职位,工资,将其放到另外一张表的一个字段中。

                    用到了我们上一篇文章用的emp表,没有那张表去上一个文章找找。



                      create table t2 (info varchar);
                      create or replace function emp_for_fun()
                      returns void as $$ -- 这里的返回类型也可以是record
                      declare
                      i record ; --record 这个类型是pg独有的,其实这也不是一个数据类型,这个就是一个记录类似行变量的占位符。
                      for i in select ename,job,sal from emp loop
                      insert 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 $$
                            declare
                            n numeric :=0;
                            begin
                            while n <10 loop
                            n:=n+1;
                            continue when n=5;
                            raise notice 'n 当前值为:%',n;
                            end loop;
                            end;
                            $$ language plpgsql;
                            复制

                            结果

                              vastbase=# select con_fun();
                              NOTICE: n 当前值为:1
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:2
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:3
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:4
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:6
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:7
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:8
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:9
                              CONTEXT: referenced column: con_fun
                              NOTICE: n 当前值为:10
                              CONTEXT: referenced column: con_fun
                              con_fun
                              ---------
                              (1 row)
                              复制


                              exit语句

                                exit [label][when boolean-expression];
                                复制

                                exit 是在执行过程中只要when boolean-expression为真,会跳出循环,循环不再进行。

                                示例:

                                  create or replace function con_fun_eixt()
                                  returns void as $$
                                  declare
                                  n numeric :=0;
                                  begin
                                  while n <10 loop
                                  n:=n+1;
                                  exit when n=5;
                                  raise notice 'n 当前值为:%',n;
                                  end loop;
                                  end;
                                  $$ language plpgsql;
                                  复制

                                  结果:

                                    vastbase=# select con_fun_eixt();
                                    NOTICE: n 当前值为:1
                                    CONTEXT: referenced column: con_fun_eixt
                                    NOTICE: n 当前值为:2
                                    CONTEXT: referenced column: con_fun_eixt
                                    NOTICE: n 当前值为:3
                                    CONTEXT: referenced column: con_fun_eixt
                                    NOTICE: n 当前值为:4
                                    CONTEXT: referenced column: con_fun_eixt
                                    con_fun_eixt
                                    --------------
                                    (1 row)
                                    复制


                                                                                                                        THAT'S ALL

                                                                                                                        BY CUI PEACE!!!

                                    文章转载自最帅dba工作笔记,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                    评论