--######################################--
--控制语句(条件语句、循环语句)
--王林 2012.07.06
--######################################--
--between 包含边界值
--**指数运算
--单变量表达式返回true、false或null。当评估某个表达式是否为true时,false和null都是not true
--同样,当评估某个表达式是否为false时,true和null都是not false。null表达式不是true也不是false。
--######################################--
--1.IF语句
--所有语句块至少需要一条语句。
--ELSIF 不能写成 ELSEIF。
--布尔变量可以取代比较运算,返回布尔数据类型的单个函数也可以。
--(1)if-then-else语句 单分支语句
--Demo1:
BEGIN
--比较语句外的括号不是必需的
IF 1 = 1 THEN
DBMS_OUTPUT.put_line( 'Condition met!' );
--没有else块的if语句只在条件满足时执行代码
END IF;
END;
--Demo2:
DECLARE
equal BOOLEAN NOT NULL := TRUE;
BEGIN
--如果评估变量或返回null值的表达式,运行时可能产生null,应用nvl避免
IF equal THEN
DBMS_OUTPUT.put_line( 'Condition met!' );
END IF;
END;
--Demo3:
BEGIN
IF 1 = 2 THEN
DBMS_OUTPUT.put_line( 'Condition met!' );
ELSE
DBMS_OUTPUT.put_line( 'Condition not met!' );
END IF;
END;
--(2)if-then-elsif-then-else 语句
--Demo4:
DECLARE
equal BOOLEAN NOT NULL := TRUE;
BEGIN
--在判定第一个条件为true后退出,当没有条件满足时,运行默认的else条件
IF 1 = 1 THEN
DBMS_OUTPUT.put_line( 'Condition 1 met!' );
ELSIF equal THEN
DBMS_OUTPUT.put_line( 'Condition 2 met!' );
ELSIF 1 =2 THEN
DBMS_OUTPUT.put_line( 'Condition 3 met!' );
END IF;
END;
--######################################--
--2.CASE语句
--不可以省去else块,否则在未发现选择符时会引发CASE_NOT_FOUND或PLS-06592错误
--简单CASE语句的选择符是使用(或返回)有效数据类型(布尔类型除外)的变量或函数。
--搜索CASE语句选择符是布尔变量或返回布尔变量的函数,默认选择true
--(1)简单CASE语句
--在整个结构中,选择变量的值同表达式的值进行顺序匹配,如果相等,则执行相应的语句序列,如果不等,则执行ELSE部分的语句序列。
--Demo5:
DECLARE
--选择符可以是除BLOB,BFILE外的任何PL/SQL数据类型或复合类型
selector NUMBER := 0;
BEGIN
CASE selector
--WHEN块越多,有效性越低
WHEN 0 THEN
--CASE语句停止评估并在退出该语句前运行匹配的WHEN块
DBMS_OUTPUT.put_line( 'Case 0!' );
WHEN 1 THEN
DBMS_OUTPUT.put_line( 'Case 1!' );
ELSE
DBMS_OUTPUT.put_line( 'No match' );
END CASE;--END 后面有CASE
END;
--(2)表达式结构CASE语句
--CASE结构还能以赋值表达式的形式出现,它根据选择变量的值求得不同的结果。
--Demo6:
--说明:该CASE表达式通过判断变量selector的值,对变量v_result赋予不同的值。
DECLARE
selector NUMBER := 1;
v_result VARCHAR2 (20);
BEGIN
v_result:=
CASE selector
WHEN 1 THEN
'First'
WHEN 2 THEN
'Second'
ELSE
'NO'
END;
DBMS_OUTPUT.PUT_LINE('The result is:'||v_result);
END;
--(3)CASE搜索语句
--它没有选择变量,直接判断条件表达式的值,根据条件表达式决定转向。
--除非想要搜索false条件,否则CASE搜索语句的选择符是隐式设置的TRUE;
--Demo7:
--说明:此结构类似于IF-THEN-ELSIF-ELSE-END IF结构。
BEGIN
CASE /*FALSE | TRUE*/
WHEN 1 = 2 THEN
DBMS_OUTPUT.put_line( '[ 1 = 2]!' );
WHEN 2 =2 THEN
DBMS_OUTPUT.put_line( '[ 2 = 2]!' );
ELSE
DBMS_OUTPUT.put_line( 'No match' );
END CASE;
END;
--######################################--
--3.Exit When循环:
--EXIT用于在循环过程中退出循环,WHEN用于定义EXIT的退出条件。如果没有WHEN条件,遇到EXIT语句则无条件退出循环。
--Demo8:
DECLARE
i NUMBER;
BEGIN
i := 0;
LOOP
EXIT WHEN( i > 5 );
DBMS_OUTPUT.put_line(i);
i := i + 1;
END LOOP;
END;
--######################################--
--4.Loop循环:
--Demo9:
DECLARE
i NUMBER;
BEGIN
i := 0;
LOOP
i := i + 1;
DBMS_OUTPUT.put_line(i);
IF i > 5 THEN
EXIT;
END IF;
END LOOP;
END;
--######################################--
--5.WHILE LOOP循环:
--WHILE循环是有条件循环
--当条件满足时,执行循环体;当条件不满足时,则结束循环。如果第一次判断条件为假,则不执行循环体。
--Demo10:
DECLARE
i NUMBER;
BEGIN
i:=0;
WHILE i < 5 LOOP
i := i + 1;
DBMS_OUTPUT.put_line(i);
END LOOP;
END;
--######################################--
--6.FOR普通循环:
--是固定次数循环。
--循环控制变量是隐含定义的,不需要声明。
--下限和上限用于指明循环次数。正常情况下循环控制变量的取值由下限到上限递增,REVERSE关键字表示循环控制变量的取值由上限到下限递减。
--跟在IN REVERSE后面的数字必须是从小到大的顺序,而且必须是整数,不能是变量或表达式。
--可以使用EXIT退出循环。
--Demo11:
DECLARE
i NUMBER;
BEGIN
i := 0;
FOR i IN 1..5 LOOP
DBMS_OUTPUT.put_line(i);
END LOOP;
END;
--Demo12:
--效果同Demo11一样
BEGIN
FOR i IN 1..5 LOOP
DBMS_OUTPUT.put_line(i);
END LOOP;
END;
--Demo13:
--REVERSE倒置计数
BEGIN
FOR i IN REVERSE 1..5 LOOP
DBMS_OUTPUT.put_line(i);
END LOOP;
END;
--######################################--
--7.For游标循环:
--Demo14:
DECLARE
userRow scott.emp%ROWTYPE;
CURSOR userRows
IS
SELECT * FROM scott.emp;
BEGIN
FOR userRow IN userRows LOOP
DBMS_OUTPUT.put_line(userRow.ename||','||userRow.empno||','||userRows%ROWCOUNT);
END LOOP;
END;