Oracle学习 第15天
—— PL/SQL 编程(控制语句)
PL/SQL控制结构
条件分支语句
与其他编程语言一样。PL/SQL的条件分支语句也是三种结构:
① if 条件 then 执行体; endif
② if 条件 then 执行体; else 执行体; -- endif
③ if 条件 then 执行体; elsif 条件 then 执行体; -- elsif … then … else 执行体 ; endif
★ 注意:在 PL/SQL 中,elsif 作为 条件转折的关键字。
示例:
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 950.00 30
7902 FORD ANALYST 7566 1981/12/3 3000.00 20
7934 MILLER CLERK 7782 1982/1/23 1400.00 10
14 rows selected
SQL>
SQL> -- 创建过程,输入员工号。如果该员工是10号部门,月薪扣掉50;如果是20号部门,月薪加40;如果其他部门,增加10元
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_in_empno NUMBER) IS
2 -- 定义工资变量
3 v_sal emp.sal%TYPE;
4 -- 定义部门变量
5 v_deptno emp.deptno%TYPE;
6 BEGIN
7 SELECT deptno, sal INTO v_deptno, v_sal FROM emp WHERE empno = v_in_empno;
8 IF v_deptno = 10 THEN
9 UPDATE emp SET sal = sal - 50 WHERE empno = v_in_empno;
10 ELSIF v_deptno = 20 THEN
11 UPDATE emp SET sal = sal + 40 WHERE empno = v_in_empno;
12 ELSE
13 UPDATE emp SET sal = sal + 10 WHERE empno = v_in_empno;
14 END IF;
15 END;
16 /
Procedure created
SQL> exec pro_test(7934);
PL/SQL procedure successfully completed
SQL> exec pro_test(7902);
PL/SQL procedure successfully completed
SQL> exec pro_test(7900);
PL/SQL procedure successfully completed
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
14 rows selected
循环控制语句
LOOP 基本语法:
LOOP
执行体;
EXIT WHEN 条件
END LOOP
示例:
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
14 rows selected
SQL>
SQL> -- 我们使用PL/SQL的控制语句来简单的实现emp表的一次性添加 n 条姓名为 指定字符+编号 的数据
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_in_name VARCHAR2, v_in_num NUMBER) IS
2 -- 定义计数变量
3 v_num emp.empno%TYPE := 1; -- 赋初始值
4 BEGIN
5 LOOP
6 -- 执行添加操作
7 INSERT INTO emp(empno, ename) VALUES(v_num, v_in_name || TO_CHAR(v_in_num));
8 v_num := v_num + 1; -- PL/SQL 没有 ++ 写法。赋值符号为 :=
9 EXIT WHEN v_num > v_in_num;
10 END LOOP;
11 END;
12 /
Procedure created
SQL> exec pro_test('TEST', 5);
PL/SQL procedure successfully completed
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
1 TEST5
2 TEST5
3 TEST5
4 TEST5
5 TEST5
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
19 rows selected
WHILE 基本语法:
WHERE 条件 LOOP
执行体;
END LOOP
示例:
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
14 rows selected
SQL>
SQL> -- 使用 Where 语句循环向 emp 表中插入 n 条数据
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_in_name VARCHAR2, v_in_num NUMBER) IS
2 -- 定义计数变量
3 v_num emp.empno%TYPE := 9000;
4 BEGIN
5 WHILE v_num <= 9000 + v_in_num
6 LOOP
7 INSERT INTO emp(empno, ename) VALUES(v_num, v_in_name);
8 v_num := v_num + 1;
9 END LOOP;
10 END;
11 /
Procedure created
SQL> exec pro_test('TESTWhile', 5);
PL/SQL procedure successfully completed
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
9000 TESTWhile
9001 TESTWhile
9002 TESTWhile
9003 TESTWhile
9004 TESTWhile
9005 TESTWhile
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
20 rows selected
FOR 基本语法:
BEGIN
FOR i IN REVERSE 1..10 LOOP -- i 每执行一次循环会自动增加 从 1 开始 到 10 结束。 1 10 可以自行定义
执行体;
END LOOP;
END;
示例:
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
14 rows selected
SQL>
SQL> CREATE OR REPLACE PROCEDURE pro_test(v_in_name VARCHAR2) IS
2 BEGIN
3 FOR i IN REVERSE 1..3 LOOP
4 INSERT INTO emp(empno, ename) VALUES(i, v_in_name);
5 END LOOP;
6 END;
7 /
Procedure created
SQL> exec pro_test('TESTFor');
PL/SQL procedure successfully completed
SQL> SELECT * FROM emp;
EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO
----- ---------- --------- ----- ----------- --------- --------- ------
3 TESTFor
2 TESTFor
1 TESTFor
7369 SMITH CLERK 7902 1980/12/17 1800.00 20
7499 ALLEN SALESMAN 7698 1981/2/20 1600.00 300.00 30
7521 WARD SALESMAN 7698 1981/2/22 1250.00 500.00 30
7566 JONES MANAGER 7839 1981/4/2 2975.00 20
7654 MARTIN SALESMAN 7698 1981/9/28 1250.00 1400.00 30
7698 BLAKE MANAGER 7839 1981/5/1 2850.00 30
7782 CLARK MANAGER 7839 1981/6/9 2450.00 10
7788 SCOTT ANALYST 7566 1987/4/19 3000.00 20
7839 KING PRESIDENT 1981/11/17 5000.00 10
7844 TURNER SALESMAN 7698 1981/9/8 1500.00 0.00 30
7876 ADAMS CLERK 7788 1987/5/23 1100.00 20
7900 JAMES CLERK 7698 1981/12/3 960.00 30
7902 FORD ANALYST 7566 1981/12/3 3040.00 20
7934 MILLER CLERK 7782 1982/1/23 1350.00 10
17 rows selected
GOTO 语句
GOTO语句用于跳转到指定位置。
很多编程语言都不允许使用GOTO语句或者保留了GOTO语句的使用。
因为GOTO语句的优点和缺点是在太过明显。
GOTO语句因其强大的跳转能力,使得编写程序非常容易;但是同时,也使得代码的逻辑性、可读性非常差,并且维护难度会很高。
所以,并不建议在编写代码的时候使用GOTO语句。
GOTO语句没有什么固定的语法。
GOTO 语句的标号使用两层尖括号 << 标号 >>
在代码的几乎是任意一行,插入标号。然后就可以通过 GOTO 标号 语句跳转到标号所在位置。
GOTO后面加标号即可,无需尖括号。
NULL语句
NULL语句不会执行任何操作,并将控制权传递给下一行代码。
实际上,NULL语句写与不写几乎不会对代码造成任何影响。
NULL语句最大的优点是提高代码的可读性。常用于循环、判断等语句中。
示例:
…
IF empno = 10 THEN
执行语句;
ELSE
NULL; -- 不执行任何操作
END IF;
…