编写控制结构
1、PL/SQL块
一个PL/SQL块由定义部分、执行部分和例外处理部分组成,其中定义部分和例外处理部分可选,而执行部分是必须的。
语法:
DECLARE
--定义常量、变量、游标、复杂数据类型、例外等
BEGIN
--PL/SQL和SQL语句
EXCEPTION
--处理可能发生的错误
END;
2、通过在PL/SQL块中嵌入SELECT语句,可以将数据库中数据检索到变量中,然后可以输出或处理该变量中的数据。
注:
①当在PL/SQL中嵌入SELECT语句时,必须要带有INTO子句 。
②当在PL/SQL块中直接使用SELECT...INTO...时,该语句必须并且只能返回一条数据,否则会触发例外并显示错误信息。
语法: SELECT select_list
INTO (variable_name1[,variable_name2,.......,Record_name])
FROM table
WHERE condition;
select_list:用于指定查询列表; variable_name:用于指定接收结果的标量变量名;
Record_name用于指接收结果的记录变量名;
例:使用标量变量接收数据
DECLARE
V_NAME DEPT.DNAME%TYPE;
V_LOC DEPT.LOC%TYPE;
BEGIN
SELECT DNAME,LOC INTO V_NAME,V_LOC FROM DEPT WHERE DEPTNO=&N;
DBMS_OUTPUT.PUT_LINE(V_NAME||' '||V_LOC);
END;
输入:N=10 输出:ACCOUNTING NEW YORK
3、条件分支语句
语法: IF condition THEN
statement;
ELSIF conditon THEN
statement;
....
ELSE
statement;
END IF;
例2:DECLARE
V_DEPTNO DEPT.DEPTNO%TYPE;
BEGIN
SELECT DEPTNO INTO V_DEPTNO FROM DEPT WHERE DNAME='SALES';
IF V_DEPTNO=10 THEN
DBMS_OUTPUT.PUT_LINE('地点: NEW YORK');
ELSIF V_DEPTNO=20 THEN
DBMS_OUTPUT.PUT_LINE('地点: DALLAS');
ELSIF V_DEPTNO=30 THEN
DBMS_OUTPUT.PUT_LINE('地点: CHICAGO');
ELSE
DBMS_OUTPUT.PUT_LINE('地点: BOSTON');
END IF;
END;
输出: 地点: CHICAGO
4、CASE语句
Ⅰ、在CASE语句中使用单一选择符进行等值比较。适用情况:如果条件选择符完全相同,并且条件表达式为相等条件选择。
语法:
CASE selector
When expression1 Then statement1;
......
When expressionN Then statementN;
ELSE
statement;
END CASE;
selector:用于指定条件选择符; expression:用于指定条件值的表达式;statement:用于指定要执行的操作;
注:为了避免CASE_NOT_FOUND例外,在使用CASE语句时,应加上ELSE子句。
例3:
DECLARE
V_DEPTNO DEPT.DEPTNO%TYPE;
BEGIN
V_DEPTNO:=&N;
CASE V_DEPTNO
WHEN 10 THEN dbms_output.put_line('地点: NEW YORK');
WHEN 20 THEN dbms_output.put_line('地点: DALLAS');
WHEN 30 THEN dbms_output.put_line('地点: CHICAGO');
WHEN 40 THEN dbms_output.put_line('地点: BOSTON');
ELSE
dbms_output.put_line('无对应的地点');
END CASE;
END;
输入:40 输出: 地点: BOSTON
Ⅱ、在CASE语句中使用多种条件比较。适用情况:除上面外
语法:
CASE
When Search_condition1 Then statement1;
.......
When Search_conditionN Then statementN;
ELSE
statement;
END CASE;
Serach_condition:用于指定不同比较条件;statement:用于指定要执行的操作。
注:为了避免CASE_NOT_FOUND例外,在使用CASE语句时,应加上ELSE子句。
例4:
DECLARE
score Number(3,1);
BEGIN
score:=&N;
CASE
WHEN score<60 THEN dbms_output.put_line('不及格');
WHEN score between 60 and 70 THEN dbms_output.put_line('及格');
WHEN score between 71 and 85 THEN dbms_output.put_line('良好');
WHEN score>85 THEN dbms_output.put_line('优秀');
END CASE;
END;
输入:90 输出:优秀
5、循环语句
①基本循环
LOOP
statement1;
......
statementN;
[EXIT When Conditions] --可放在基本循环的任何地方,一个基本循环可以有多条EXIT语句
END LOOP;
当使用基本循环时,无沦是否满足条件,语句至少会被执行一次。当Conditions为TRUE时,会退出循环,并执行
END LOOP后的相应操作。当编写基本循环时,一定要包含EXIT语句,否则PL/SQL块会陷入死循环。
注:当使用基本循环时,应当定义循环控制变量,并在循环体内改变循环控制变量的值。
例1:
declare
i int;
begin
I:=1;
LOOP
EXIT WHEN I=11;
INSERT INTO TEMP VALUES(I);
EXIT WHEN I=10;
I:=I+1;
END LOOP;
END;
②While循环
While Conditions LOOP
statement1;
......
statementN;
[EXIT When Conditions] --可放在WHILE循环的任何地方,一个WHILE循环可以有多条EXIT语句
END LOOP;
注:当使用While循环时,应当定义循环控制变量,并在循环体内改变循环控制变量的值。
例2:
declare
i int;
begin
I:=1;
While i<11 loop
insert into temp values (i);
i:=i+1;
END LOOP;
END;
③For循环
FOR count in [REVERSE]
lower_bound..upper_bound LOOP
statement1;
......
statementN;
[EXIT When Conditions] --可放在for循环的任何地方,一个for循环可以有多条EXIT语句
END LOOP;
count是循环控制变量,并且该变量由oracle隐含定义,不需要显式定义。lower_bound..upper_bound分别对应于循环控制变量的下界值和上界值。默认情况下,当使用FOR循环时,每次循环时循环控制变量会自动增1。如果指定REVERSE选项时,每次循环时循环控制变量会自动减1。
例3_1:
begin
FOR I IN 1..10 LOOP
insert into temp values (i);
END LOOP;
END;
例3_2:
begin
FOR I IN reverse 1..10 LOOP
insert into temp values (i);
END LOOP;
END;
例3_3:
begin
FOR I IN reverse 1..10 LOOP
exit when i=5;
insert into temp values (i);
END LOOP;
END;
6、标号:定义格式:<<LABE_NAME>>
7、顺序控制语句
goto label_name;
goto语句用于跳转到特定标号处去执行语句。label_name是已经定义的标号名,当使用goto跳转到特定标号时,标号后至少要包含一条可执行语句。
例1:
DECLARE
I INT DEFAULT 1;
BEGIN
LOOP
I:=I+1;
IF I=10 THEN
GOTO OUT_LOOP;
END IF;
END LOOP;
<<OUT_LOOP>>
DBMS_OUTPUT.put_line('基本循环结束,I='||I);
END;
输出:基本循环结束,I=10
8、NULL语句
格式:NULL;
NULL语句不会执行任何操作,并且会直接将控制传递到下一条语句。使用NULL语句主要是为了提高程序的可读性。
例1:
SQL> BEGIN
2 FOR I IN 1..10 LOOP
3 IF i mod 2=1 THEN
4 INSERT INTO TEMP VALUES(I);
5 ELSE
6 NULL;
7 END IF;
8 END LOOP;
9 END;
10 /
PL/SQL procedure successfully completed
SQL> SELECT * FROM TEMP;
COL
---------------------------------------
1
3
5
7
9