PostgreSQL存儲過程(3)-流程控制語句


流程控制

 講解條件語句,循環語句。

本次環境會用到表emp;下面是emp執行語句。

drop table emp;
create table EMP(
EMPNO numeric(4) not null,
ENAME varchar(10),
JOB varchar(9),
MGR numeric(4),
HIREDATE date,
SAL numeric(7 ),
COMM numeric(7 ),
DEPTNO numeric(2));

insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7369, 'SMITH', 'CLERK', 7902, to_date('1980-12-17', 'YYYY-MM-DD'), 800, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7499, 'ALLEN', 'SALESMAN', 7698, to_date('1981-02-20', 'YYYY-MM-DD'), 1600, 300, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7521, 'WARD', 'SALESMAN', 7698, to_date('1981-02-22', 'YYYY-MM-DD'), 1250, 500, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7566, 'JONES', 'MANAGER', 7839, to_date('1981-04-02', 'YYYY-MM-DD'), 2975, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7654, 'MARTIN', 'SALESMAN', 7698, to_date('1981-09-28', 'YYYY-MM-DD'), 1250, 1400, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7698, 'BLAKE', 'MANAGER', 7839, to_date('1981-05-01', 'YYYY-MM-DD'), 2850, null, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7782, 'CLARK', 'MANAGER', 7839, to_date('1981-06-09', 'YYYY-MM-DD'), 2450, null, 10);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7788, 'SCOTT', 'ANALYST', 7566, to_date('1987-04-19', 'YYYY-MM-DD'), 3000, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7839, 'KING', 'PRESIDENT', null, to_date('1981-11-17', 'YYYY-MM-DD'), 5000, null, 10);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7844, 'TURNER', 'SALESMAN', 7698, to_date('1981-09-08', 'YYYY-MM-DD'), 1500, 0, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7876, 'ADAMS', 'CLERK', 7788, to_date('1987-05-23', 'YYYY-MM-DD'), 1100, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7900, 'JAMES', 'CLERK', 7698, to_date('1981-12-03', 'YYYY-MM-DD'), 950, null, 30);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7902, 'FORD', 'ANALYST', 7566,to_date('1981-12-02', 'YYYY-MM-DD'), 3000, null, 20);
insert into EMP (EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM, DEPTNO)
values (7934, 'MILLER', 'CLERK', 7782, to_date('1982-01-23', 'YYYY-MM-DD'), 1300, null, 10);
View Code

1. 條件語句

 IF和CASE語句讓你可以根據某種條件執行命令。

 PL/pgSQL有三種形式的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條件語句

語法結構:

IF search_condition THEN
  statement_list
END IF;
-----------------------
IF search_condition THEN
    statement_list
ELSE
    statement_list
END IF;
-----------------------
IF search_condition THEN
    statement_list
ELSIF search_condition THEN
    statement_list
ELSE
    statement_list
END IF;

案例1:給員工薪水少於1500元提示“多加工資”;反之。

CREATE OR REPLACE FUNCTION if_test(vc_empno NUMERIC)
RETURNS void
AS $$
DECLARE
vn_sal numeric;
BEGIN
    select sal into vn_sal from emp where empno = vc_empno;
    IF vn_sal is null THEN
     RAISE NOTICE '該員工不存在!';
    ELSIF vn_sal < 1500 THEN
     RAISE NOTICE '老板;請多加點工資';
    ELSE
     RAISE NOTICE '老板;請少加點工資';     
    END IF;
END;
$$ LANGUAGE PLPGSQL;

調用測試

lottu=# SELECT if_test(7399);
NOTICE:  該員工不存在!

lottu=# SELECT if_test(7369);
NOTICE:  老板;請多加點工資

lottu=# SELECT if_test(7566);
NOTICE:  老板;請少加點工資

1.2 CASE條件語句

-- 
CREATE
OR REPLACE FUNCTION case_test1(x NUMERIC) RETURNS void AS $$ DECLARE msg text; BEGIN CASE x WHEN 1, 2 THEN msg := 'one or two'; ELSE msg := 'other value than one or two'; END CASE; RAISE NOTICE 'look it, it is %' ,msg; END; $$ LANGUAGE PLPGSQL; CREATE OR REPLACE FUNCTION case_test2(x NUMERIC) RETURNS void AS $$ DECLARE msg text; BEGIN -- msg := CASE WHEN x in (1,2) THEN 'one or two' ELSE 'other value than one or two' END; CASE WHEN x in (1,2) THEN msg := ''one or two''; ELSE msg := 'other value than one or two'; END CASE; RAISE NOTICE 'look it, it is %' ,msg; END; $$ LANGUAGE PLPGSQL;

2.循環

2.1 簡單循環

[ <<label>> ]
LOOP
    statements
    EXIT [ label ] [ WHEN boolean-expression ];
END LOOP [ label ];
  • LOOP定義一個無條件的循環,無限循環,直到由EXIT或RETURN語句終止。
  • 可選的label可以由EXIT和CONTINUE語句使用,用於在嵌套循環中聲明應該應用於哪一層循環。
  • 如果聲明了WHEN,循環退出只有在boolean-expression為真的時候才發生, 否則控制會落到EXIT后面的語句上。

案例1:輸出一個1-10的列表

CREATE OR REPLACE FUNCTION LOOP_TEST_01()
RETURNS void
AS $$
DECLARE
n numeric := 0;
BEGIN
  LOOP
    n := n + 1;
    RAISE NOTICE 'n 的當前值為: %',n;
    EXIT WHEN n >= 10;
  END LOOP;
END;
$$ LANGUAGE PLPGSQL;

2.2 WHILE 循環

語法:

WHILE boolean-expression LOOP
    statements;
END LOOP;

只要條件表達式(boolean-expression)為真,WHILE語句就會不停的在一系列語句上進行循環, 條件是在每次進入循環體的時候檢查的。

CREATE OR REPLACE FUNCTION LOOP_TEST_02()
RETURNS void
AS $$
DECLARE
n numeric := 0;
BEGIN
    WHILE n < 10 LOOP
    n := n + 1;
    RAISE NOTICE 'n 的當前值為: %',n;
  END LOOP;
END;
$$ LANGUAGE PLPGSQL;

2.3. FOR (integer variant)

語法:

FOR name IN [ REVERSE ] expression .. expression [ BY expression ] LOOP
    statements
END LOOP [ label ];

每循環一次,循環變量自動加1;使用關鍵字REVERSE,循環變量自動減1。跟在IN REVERSE 后面的數字必須是從小到大的順序,而且必須是整數,不能是變量或表達式。可以使用EXIT 退出循環。

FOR i IN 1..10 LOOP
    -- i will take on the values 1,2,3,4,5,6,7,8,9,10 within the loop
END LOOP;

FOR i IN REVERSE 10..1 LOOP
    -- i will take on the values 10,9,8,7,6,5,4,3,2,1 within the loop
END LOOP;

FOR i IN REVERSE 10..1 BY 2 LOOP
    -- i will take on the values 10,8,6,4,2 within the loop
END LOOP;

2.4 for遍歷命令結果

語法:

FOR target IN query LOOP
    statements
END LOOP [ label ];

這種在實際工作過程中;由於需要用到游標,經常用它來替換游標。

在這里注意到是:i變量必須要聲明為RECORD; 這在oracle的存儲過程沒這個設置。

CREATE OR REPLACE FUNCTION LOOP_TEST_03()
RETURNS void
AS $$
DECLARE
    i RECORD;
BEGIN
   FOR i IN select ename,job from emp where deptno = 20 loop
     RAISE NOTICE '% job is %', i.ename ,i.job;
   end loop;     
END;
$$ LANGUAGE PLPGSQL;

 

2.5 CONTINUE語句

語法:

CONTINUE [ label ] [ WHEN boolean-expression ];

CONTINUE可以用於所有類型的循環;它並不僅僅限於無條件循環,不會跳出循環。

CREATE OR REPLACE FUNCTION LOOP_TEST_04()
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;

2.6 EXIT語句

語法:

EXIT [ label ] [ WHEN boolean-expression ];

EXIT可以用於在所有的循環類型中,它並不僅僅限制於在無條件循環中使用。 會跳出循環。

CREATE OR REPLACE FUNCTION LOOP_TEST_05()
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;

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM