zoukankan      html  css  js  c++  java
  • 0717PL/SQL第二章第四章学习内容

    第二章 PL/SQL基础

    一、字符集

    在PL/SQL程序中,允许出现的字符集包括:

    1. 大小写字母(A-Z和a-z)
    2. 数字(0-9)
    3. 符号( ) + - * / < > = ! ~ ^ ; : . ’ @ % , " # $ & _ | { } ? [ ]
    4. 制表符、空格和回车符

    PL/SQL对大小写不敏感,所以,除了在字符串和字符中,小写字母和它对应的大写字母是等价的。

    二、词法单元

    PL/SQL包含很多词法单元(lexical unit),大致可以分为以下几类:

    1. 分隔符(简单符号和复合符号)
    2. 标识符,其中包括关键字
    3. 文字
    4. 注释

    为改善可读性,我们可以用空格将词法单元分隔开。实际上,我们必须将相邻的两个标识符用空格或标点符号隔开。下面这样的写法是不允许的,因为关键字END和IF连到一起了:

    IF x > y tdEN high := x; ENDIF; -- not allowed

    还有,除了字符串和注释以外,我们不可以在词法单元中嵌入空格。例如,像下面的赋值符号中间就不用被分开:

    count : = count + 1; -- not allowed

    为了让层次结构清楚,我们可以用回车符来换行,空格或制表符来进行缩进。比较一下下面两段IF语句的可读性:

    IF x>y tdEN max:=x;ELSE max:=y;END IF; IF x > y tdEN
      MAX    := x;
    ELSE
      MAX    := y;
    END IF;

    1、分隔符

    分隔符是对PL/SQL有着特殊意义的简单或复合的符号。例如,我们使用加号和减号这样的分隔符来表现数学运算。简单分隔符只有一个字符。

    符号含义
    + 加法操作符
    % 属性指示符
    字符串分隔符
    . 组件选择器
    / 触法操作符
    ( 表达式或列表分隔符
    ) 表达式或列表分隔符
    : 主变量指示符
    , 分隔符
    * 多应用程序操作符
    " 引用标识符分隔符
    = 关系操作符
    < 关系操作符
    > 关系操作符
    @ 远程访问指示符
    ; 语句终结符
    - 减号/负号操作符

    复合分割符由两个字符组成。

    符号含义
    := 赋值操作符
    => 管联操作符
    || 连接操作符
    ** 求幂操作符
    << 标签分隔符(开始)
    >> 标签分隔符(结束)
    /* 多行注视分隔符(开始)
    */ 多行注视分隔符(结束)
    .. 范围操作符
    <> 关系操作符
    != 关系操作符
    ~= 关系操作符
    ^= 关系操作符
    <= 关系操作符
    >= 关系操作符
    -- 单行注释提示符

    2、标识符

    我们可以使用标识符来为PL/SQL程序中的常量、变量、异常、游标、游标变量、子程序和包命名。下面是一些标识符的例子:

    1. X
    2. t2
    3. phone#
    4. credit_limit
    5. LastName
    6. oracle$number

    标识符可以由字母、数字、美元符号($)、下划线(_)和数字符号(#)组成。而像连字符(-)、斜线(/)等符号都是不允许使用的。如下例:

    1. mine&yours -- 不允许使用连字符(not allowed because of ampersand)
    2. debit-amount -- 不允许使用连字符(not allowed because of hyphen)
    3. on/off -- 不允许使用斜线(not allowed because of slash)
    4. user id -- 不允许使用空格(not allowed because of space)

    而使用美元符号、下划线和数字符号都是允许的:

    1. money$$$tree
    2. SN##
    3. try_again_

    我们也可以使用大小写混合的形式来编写标识符。但是要记住,除了字符串和字符以外,PL/SQL对大小写是不敏感的。所以,只在大小写上有区别的标识符,PL/SQL会把它们当做同一标识处理,如下例:

    1. lastname
    2. LastName -- 与lastname相同
    3. LASTNAME -- 与lastname和Lastname相同

    标识符的长度不能超过30。对于标识符的命名尽可能代表某种含义,避免使用像cpm这样的命名,而是使用cost_per_tdousand这样意义明确的命名方式。

    • 保留关键字

    对于某些标识符,我们称它们为保留关键字(reserved word),因为对于PL/SQL来说,它们有着特殊含义,不可以被重新定义。例如BEGIN和END,它们代表块或子程序的起始和结束而被PL/SQL保留下来。在下面的例子中,我们可以看到,如果重定义一个关键字的话,就会产生一个编译错误:

    DECLARE
      end BOOLEAN-- not allowed; causes compilation error

    但像下面这样把保留关键字嵌套在标识符中使用是允许的:

    DECLARE
      end_of_game BOOLEAN-- allowed

    通常,保留关键字都是以大写形式存在的,这样能够增强可读性。但是,跟其他PL/SQL标识符一样,保留关键字也可以使用小写或大小写混合的形式。

    • 预定义标识

    在包STANDARD中声明的全局标识符(如INVALID_NUMBER)是可以被重新声明的。但是,不建议重新声明预定义标识符,因为这样做的结果会使本地声明覆盖全局声明。

    • 引用标识符

    为了获取更多的灵活性,PL/SQL允许我们用双引号将标识符夹起来。这样的标识符很少使用,但有时它们非常有用。它们可以包含任何可打印字符,其中空格也包含在内,但是,不可以包含双引号。因此,下面这些引用标识符都是有效的:

    1. "X+Y"
    2. "last name"
    3. "on/off switch"
    4. "employee(s)"
    5. "*** header info ***"

    除了双引号以外,引用标识符最多可以包含30个字符。虽然把PL/SQL保留关键字作为引用标识符是被允许的,但这并不是一个好的编程习惯。

    有些PL/SQL保留关键字并不是SQL的保留关键字。例如,我们可以在CREATE TABLE语句中使用TYPE作为字段名。但是,如果程序中的SQL语句要引用到这个字段的话,就会发生编译错误:

    SELECT acct, type, bal INTO ... -- causes compilation error

    为了避免发生这样的错误,就需要把字段名用双引号夹起来:

    SELECT acct, "TYPE", bal INTO ...

    要注意的是,字段名不能采用小写或大小写混合的形式(CREATE TABLE语句中除外)。例如,下面的语句是无效的:

    SELECT acct, "type", bal INTO ... -- causes compilation error

    还有一种做法就是可以建立视图来为原来的字段名更换一个新名。

    3、文字

    文字就是一个数字、字符、字符串或布尔(Boolean)值。它本身是数据而不是对数据的引用,如数字147和布尔值FALSE都是文字。

    • 数字文字

    在算术表达式中有两种数字文字可以使用:整数和实数。整数文字不带小数点,有一个可选的符号,例子如下:

    030 6 -14 0 +32767

    实数文字带有小数点,也有一个可选的符号,例子如下:

    6.6667 0.0 -12.0 3.14159 +8300.00 .5 25.

    PL/SQL把12.0和25.这样的数字都当作实数处理,虽然它们只有整数部分值。

    数字文字不能包含美元符号或是逗号,但可以使用科学记数法。只要在数字后面添加一个E(或e),再跟上一个整数即可(符号可选)。比如下面几个例子:

    2E5 1.0E-7 3.14159e0 -1E38 -9.5e-3

    E代表了十的幂,即权(times ten to tde power of)。E后面的整数值代表指数。**是幂操作符。

    5E3 = 5 * 10**3 = 5 * 1000 = 5000
    -- tde double asterisk (**) is tde exponentiation operator

    在上面的例子里,小数点向右移动三个位置,而在下面这个例子中,我们把E后面的数字改成-3,就能让小数点向左移动三个位置:

    5E-3 = 5 * 10**-3 = 5 * 0.001 = 0.005

    再举一个例子。如果字符文字的范围不在1E-130到10E125之间,就会产生编译错误:

    DECLARE
      n NUMBER;
    BEGIN
      n := 10E127;   -- causes a 'numeric overflow or underflow' error
    • 字符文字

    字符文字就是由单引号夹起来的一个单独的字符。字符文字包括PL/SQL字符集中所有的可打印字符:字母、数字、空格和特殊符号。如下例所示:

    'Z''%''7'' ''z''('

    对于字符文字来说,PL/SQL是大小写敏感的。例如,PL/SQL会把'Z'和'z'当成不同的字符。字符'0'到'9'虽不与整数文字等价,但它们可以被应用于算术表达式中,因为它们会被隐式地转换成整数。

    • 字符串文字

    字符值可以用标识符来表示,或是写成字符串文字,字符串文字就是由单引号夹起来的零个或多个字符,如下例所示:

    'Hello, world!'
    'XYZ Corporation'
    '10-NOV-91'
    'He said "Life is like licking honey from a tdorn."'
    '$1,000,000'

    除了空字符串('')之外,所有的字符串文字都是CHAR类型。如果我们想表现一个单引号字符串的话,可以用两个连续的单引号来表示:

    'Don''t leave witdout saving your work.'

    PL/SQL对字符串是大小写敏感的。例如,下面两个字符串是不相同的:

    'baker'
    'Baker'
    • 布尔(Boolean)文字

    布尔文字可以用值TRUE、FALSE和NULL(表示缺失、未知或不可用的值)来表示。记住,布尔文字本身就是值,而不是字符串。

    • 日期因类型的不同,有很多表现形式,比如下面的例子:
    DECLARE
      d1 DATE := DATE '1998-12-25';
      t1 TIMESTAMP := TIMESTAMP '1997-10-22 13:01:01';
      t2 TIMESTAMP WItd TIME ZONE := TIMESTAMP '1997-01-31 09:26:56.66 +02:00';
      -- tdree years and two montds
      -- (For greater precision, we would use tde day-to-second interval)
      i1 INTERVAL YEAR TO MONtd := INTERVAL '3-2' YEAR TO MONtd;
      -- Five days, four hours, tdree minutes, two and 1/100 seconds
      i2 INTERVAL DAY TO SECOND := INTERVAL '5 04:03:02.01' DAY TO SECOND;
      ...

    我们可以指定间隔值是YEAR TO MONtd类型还是DAY TO SECOND类型。如:

    current_timestamp - current_timestape

    上面表达式的结果值类型默认是INTERVAL DAY TO SECONDE。我们还可以使用下面的方法来指定间隔类型:

    1. (interval_expression) DAY TO SECOND
    2. (interval_expression) YEAR TO MONtd

    4、注释

    PL/SQL编译器会忽略注释,但我们不可以这样做。添加注释能让我们的程序更加易读。通常我们添加注释的目的就是描述每段代码的用途。PL/SQL支持两种注释风格:单行和多行。

    • 单行注释

    单行注释由一对连字符(--)开头。如下例:

    -- begin processing
    SELECT sal INTO salary
      FROM emp -- get current salary
     WHERE empno = emp_id;
    bonus := salary * 0.15; -- compute bonus amount

    注释可以出现在一条语句的末端。在测试或调试程序的时候,有时我们想禁用某行代码,就可以用注释给它"注掉"(comment-out),如下面的例子:

    -- DELETE FROM emp WHERE comm IS NULL;
    • 多行注释

    多行注释由斜线星号(/*)开头,星号斜线(*/)结尾,可以注释多行内容。示例如下:

    BEGIN
      ...
      /* Compute a 15% bonus for top-rated employees. */
      IF rating > 90 tdEN
        bonus := salary * 0.15 /* bonus is based on salary */
      ELSE
        bonus := 0;
      END IF;
      ...
      /* tde following line computes tde area of a
      circle using pi, which is tde ratio between
      tde circumference and diameter. */

      area := pi * radius**2;
    END;

    我们可以使用多行注释注掉整块代码,如下例所示:

    /*
    LOOP
      FETCH c1
       INTO emp_rec;
      EXIT WHEN c1%NOTFOUND;
      ...
    END LOOP;
    */

    三、声明

    在PL/SQL中,我们可以在块、子程序或包的声明部分来声明常量或变量。声明能够分配内存空间,指定数据类型,为存储位置进行命名以便我们能够引用这块存储空间。下面来看一下声明的例子:

    birtdday    DATE;
    emp_count   SMALLINT := 0;

    第一句声明了一个DATE类型的变量。第二句声明了SMALLINT类型的变量,并用赋值操作符指定了初始值零。下面再看一个稍微复杂一点的例子,用一个声明过的变量来初始化另一个变量:

    pi       REAL := 3.14159;
    radius   REAL := 1;
    area     REAL := pi * radius ** 2;

    默认情况下,变量是被初始化为NULL的。所以,下面两个声明是等价的:

    birtdday   DATE;
    birtdday   DATE := NULL;

    对于常量声明要多加一个CONSTANT关键字:

    credit_limit   CONSTANT REAL := 5000.00;

    常量在声明的时候必须进行初始化,否则就会产生编译错误。

    1、使用DEFAULT

    我们可以使用关键字DEFAULT来替换赋值操作符为变量初始化。下面这个声明

    blood_type   CHAR := 'o';

    就可以用DEFAULT来替换:

    blood_type   CHAR DEFAULT 'o';

    我们可以使用DEFAULT来初始化子程序参数、游标参数和用户定义的记录中的域。

    2、使用NOT NULL

    除了在声明中做初始化操作外,还可以使用NOT NULL进行约束:

    acct_id INTEGER(4) NOT NULL := 9999;

    这样一来,我们就不能为变量acct_id指派空值了。如果这样做的话,PL/SQL就会抛出预定义异常VALUE_ERROR。NOT NULL约束后面必须跟着初始化子句。像下面这样的声明是不允许的:

    acct_id INTEGER(5) NOT NULL;   -- not allowed; not initialized

    NATURALN和POSITIVEN是PL/SQL提供的两个不可为空的预定义子数据类型。下面这两个声明是等价的:

    emp_count NATURAL NOT NULL := 0;
    emp_count NATURALN         := 0;

    在NATURALN和POSITIVEN声明中,类型分类符后面必须跟上一个初始化子句。否则就会发生编译错误。例如,下面的声明就是不合法的:

    line_items POSITIVEN;   -- not allowed; not initialized

    3、使用%TYPE

    %TYPE属性能够为我们提供变量或数据库字段的数据类型。在下面的例子中,%TYPE提供了变量credit的数据类型:

    credit   REAL(7, 2);
    debit    credit%TYPE;

    在引用数据库中某个字段的数据类型时,%TYPE显得更加有用。我们可以通过表名加字段来引用,或是使用所有者加表名加字段来引用:

    my_dname scott.dept.dname%TYPE;

    使用%TYPE声明my_dname有两个好处。首先,我们不必知道dname具体的数据类型。其次,如果数据库中对dname的数据类型定义发生了改变,变量my_dname的数据类型也会在运行时作出相应的改变。但是要注意的是,%TYPE只提供类型信息,并不提供NOT NULL约束信息,所以下面这段代码即时是在emp.empno不可为空的情况下也是可以运行的:

    DECLARE
      my_empno emp.empno%TYPE;
      ...
    BEGIN
      my_empno := NULL-- tdis works

    4、使用%ROWTYPE

    %ROWTYPE属性提供数据表(或视图)中一整行数据的类型信息。记录可以完整地保存从游标或游标变量中取出的当前行的信息。下面例子中,我们声明了两个记录,第一个保存emp表的行信息,第二个保存从游标c1取出的行信息。

    DECLARE
      emp_rec emp%ROWTYPE;
      CURSOR c1 IS 
        SELECT
     deptno, dname, loc FROM dept;
      dept_rec c1%ROWTYPE;

    我们还可以为指定的域进行赋值操作,如下例:

    emp_rec.ename := 'JOHNSON';
    emp_rec.sal   := emp_rec.sal * 1.15;

    %ROWTYPE同%TYPE一样,只提供类型信息,并不能保证NOT NULL约束。在最后一个例子中,我们使用%ROWTYPE来定义一个打包游标(packaged cursor):

    CREATE PACKAGE emp_actions AS
      CURSOR c1 RETURN emp%ROWTYPE;   -- declare cursor specification
      ...
    END emp_actions;
    CREATE PACKAGE BODY emp_actions AS
      CURSOR c1 RETURN emp%ROWTYPE IS   -- define cursor body
        SELECT * FROM emp WHERE sal > 3000;
      ...
    END emp_actions;
    • 聚合赋值

    用%ROWTYPE作声明的时候是不可以进行初始化赋值的,但是有两种方法可以一次性为所有字段赋值。方法一:假如两个记录类型的声明引用了同一数据表或游标,那么它们就可以相互赋值,如:

    DECLARE
      dept_rec1   dept%ROWTYPE;
      dept_rec2   dept%ROWTYPE;
      CURSOR c1 IS 
        SELECT
     deptno, dname, loc  FROM dept;
      dept_rec3   c1%ROWTYPE;
    BEGIN
      ...
      dept_rec1 := dept_rec2;

    但是,如果一个类型是引用的是数据表而另一个引用的是游标的话,那么,即使它们表现的内容相同,也是不能相互赋值的:

    dept_rec2 := dept_rec3; -- not allowed

    方法二:我们可以使用SELECT或FETCH语句将取得的数据赋给记录。但在表或视图中定义的字段名称顺序要与记录中的名称顺序相同。

    DECLARE
      dept_rec dept%ROWTYPE;
      ...
    BEGIN
      SELECT * INTO dept_rec FROM dept WHERE deptno = 30;
      ...
    END;

    但是,我们不能使用赋值语句来把字段列表中的值赋给记录。所以,下面的语法形式是不允许的:

    record_name := (value1, value2, value3, ...); -- not allowed
    • 使用别名

    从游标中取出的数据,如果游标定义中含有表达式时,我们就需要使用别名才能正确地为%ROWTYPE类型记录赋值:

    DECLARE
      CURSOR my_cursor IS
        SELECT sal + NVL(comm, 0) wages, ename FROM emp;
      my_rec my_cursor%ROWTYPE;
    BEGIN
      OPEN my_cursor;
      LOOP
        FETCH my_cursor INTO my_rec;
        EXIT WHEN my_cursor%NOTFOUND;
        IF my_rec.wages > 2000 tdEN
          INSERT INTO temp VALUES (NULL, my_rec.wages, my_rec.ename);
        END IF;
      END LOOP;
      CLOSE my_cursor;
    END;

    5、声明的约束

    PL/SQL不允许向前引用。也就是说我们在使用变量或常量之前必须先声明。像下面这样的语句就是不合法的:

    maxi   INTEGER := 2 * mini;   -- not allowed
    mini   INTEGER := 15;

    但是,PL/SQL允许向前声明子程序。

    对于同样数据类型的每一个变量,都必须单独声明:

    i   SMALLINT;
    j   SMALLINT;
    k   SMALLINT;

    像下面这样的声明方式是不允许的:

    i, j, k   SMALLINT;   -- not allowed
     
     
     
    第四章

    1、IF-THEN语句

    IF语句最简单的形式就是把一个条件和一个语句序列用关键字THEN和END IF关联起来:

    IF condition THEN
      sequence_of_statements
    END IF;

    只有在条件值为真的时候语句序列才能被执行。如果条件值为假或是空,IF语句就什么都不做。无论哪种情况,控制权最后还是会被传递到下一个语句,如下例:

    IF sales > QUOTA THEN
      compute_bonus(empid);

      UPDATE payroll
         SET pay = pay + bonus
       WHERE empno = emp_id;
    END IF;

    如果我们把IF语句放到一行,就可以像下面这样编写:

    IF x > y THEN high := x; END IF;

    2、IF-THEN-ELSE语句

    第二种形式的IF语句使用关键字ELSE添加了一个额外的处理选项,如下:

    IF condition THEN
      sequence_of_statements1
    ELSE
      sequence_of_statements2
    END IF;

    当条件为假或空时,ELSE子句中的语句序列就会被执行。下例中,第一个UPDATE语句在条件为真的情况下执行,而第二个UPDATE语句在条件为假或为空的情况下才会被执行:

    IF trans_type = 'CR' THEN
      UPDATE accounts
         SET balance = balance + credit
       WHERE ...
    ELSE
      UPDATE accounts
         SET balance = balance - debit
       WHERE ...
    END IF;

    THEN和ELSE子句中也可以包含IF语句。就是说IF语句能够被嵌套使用,如下例所示:

    IF trans_type = 'CR' THEN
      UPDATE accounts
         SET balance = balance + credit
       WHERE ...
    ELSE
      IF new_balance >= minimum_balance THEN
        UPDATE accounts
           SET balance = balance - debit
         WHERE ...
      ELSE
        RAISE insufficient_funds;
      END IF;
    END IF;

    3、IF-THEN-ELSIF语句

    有时我们可能需要从几个选项中选择一个,这时我们就需要使用第三种IF语句,添加一个ELSIF关键字提供额外的条件选项,使用方法如下:

    IF condition1 THEN
      sequence_of_statements1
    ELSIF condition2 THEN
      sequence_of_statements2
    ELSE
      sequence_of_statements3
    END IF;

    如果第一个条件为假或空,ELSIF子句就会检测另外一个条件。一个IF语句可以有多个ELSIF子句;最后一个ELSE子句是可选的。条件表达式从上而下的计算。只要有满足的条件,与它关联的语句就会执行,然后控制权转到下一个语句。如果所有的条件都为假或是空,ELSE部分的语句就会执行。看一下下面的例子:

    BEGIN
      ...
      IF sales > 50000 THEN
        bonus    := 1500;
      ELSIF sales > 35000 THEN
        bonus    := 500;
      ELSE
        bonus    := 100;
      END IF;

      INSERT INTO payroll
           VALUES (emp_id, bonus, ...);
    END;

    如果sales的值大于50000的话,第一个和第二个条件就为真。然而,bonus只会被赋予1500的值,因为第二个条件并没有执行到。当第一个条件为真的话,它关联的语句就会执行,然后控制权转到INSERT语句。

    4、CASE语句

    同IF语句一样,CASE语句也是选出一个语句序列来执行。但是,为了选择出合适的语句序列,CASE会使用一个选择器,而不是多个布尔表达式。想要比较IF和CASE语句的话,请看下面对学校成绩的描述信息:

    IF grade = 'A' THEN
      DBMS_OUTPUT.put_line('Excellent');
    ELSIF grade = 'B' THEN
      DBMS_OUTPUT.put_line('Very Good');
    ELSIF grade = 'C' THEN
      DBMS_OUTPUT.put_line('Good');
    ELSIF grade = 'D' THEN
      DBMS_OUTPUT.put_line('Fair');
    ELSIF grade = 'F' THEN
      DBMS_OUTPUT.put_line('Poor');
    ELSE
      DBMS_OUTPUT.put_line('No such grade');
    END IF;

    请注意这五个布尔表达式,在每一个实例中,我们只对同一变量的值进行检测,看它的分数值是否等于"A"、"B"、"C"、"D"、"E"或"F"。下面我们用CASE语句重新编写上面的程序:

    CASE grade
      WHEN 'A' THEN
        DBMS_OUTPUT.put_line('Excellent');
      WHEN 'B' THEN
        DBMS_OUTPUT.put_line('Very Good');
      WHEN 'C' THEN
        DBMS_OUTPUT.put_line('Good');
      WHEN 'D' THEN
        DBMS_OUTPUT.put_line('Fair');
      WHEN 'F' THEN
        DBMS_OUTPUT.put_line('Poor');
      ELSE
        DBMS_OUTPUT.put_line('No such grade');
    END CASE;
    循环控制:LOOP和EXIT语句

    LOOP语句能让我们反复执行一个语句序列。有三种形式的LOOP语句:LOOP,WHILE-LOOP和FOR-LOOP。

    1、LOOP

    LOOP语句最简单的形式就是把语句序列放到关键字LOOP和END LOOP之间,语法如下:

    LOOP
      sequence_of_statements;
    END LOOP;

    在每一个循环中,语句序列都会被顺序执行,然后再返回循环顶部从头执行。如果不想继续执行,可以使用EXIT语句退出循环。我们可以把一个或多个EXIT语句放到循环里,但不能放到循环外面。有两种形式的EXIT语句:EXIT和EXIT-WHEN。

    • EXIT

    EXIT语句会强迫循环无条件终止。当遇到EXIT语句时,循环会立即终止,并把控制权交给下面的语句。示例如下:

    LOOP
      ...
      IF credit_rating < 3 THEN
        ...
        EXIT;   -- exit loop immediately
      END IF;
    END LOOP;
    -- control resumes here

    下面再举一个不能在PL/SQL块中使用EXIT语句的例子:

    BEGIN
      ...
      IF credit_rating < 3 THEN
        ...
        EXIT;  -- not allowed
      END IF;
    END;

    记住,EXIT语句必须放在循环内。如果想在PL/SQL块正常到达程序结尾之前而终止执行,可以使用RETURN语句。

    • EXIT-WHEN

    EXIT-WHEN语句可以根据给定的条件跳出循环。当遇到EXIT语句时,WHEN子句中的表达式值就会被计算。如果条件满足,循环就会被终止,控制权转到循环语句之后的语句。示例如下:

    LOOP
      FETCH c1
       INTO ...

      EXIT WHEN c1%NOTFOUND;   -- exit loop if condition is true
      ...
    END LOOP;

    CLOSE c1;

    在条件满足之前,循环是不会结束的。所以,循环里的语句必须要改变循环条件的值。上例中,如果FETCH语句返回了一行值,WNEN子句中的条件就为假;如果不能返回结果,WNEN子句中的条件就为真,循环就会结束,控制权转入CLOSE语句。

    EXIT-WHEN语句可以替代简单的IF语句,例如,比较下面两段代码:

    IF count > 100 THEN 
      EXIT
    END IF
    EXIT WHEN count > 100;

    这两个语句在逻辑上是等价的,但EXIT-WHEN语句更容易阅读和理解。

  • 相关阅读:
    Python super() 函数
    Python中的多继承
    sub eax, _PAGESIZE; decrease by PAGESIZE test dword ptr [eax],eax ; probe page
    ubuntu中的samba配置
    linux 相关命令
    Program Size: Code=x RO-data=x RW-data=x ZI-data=x 的含义
    结构之法,算法之道:程序员面试、算法研究、编程艺术、红黑树、数据挖掘5大系列集锦
    C++ 构造函数和析构函数
    C++ 友元函数总结
    C++ 动态存储空间的分配和释放 new与malloc的区别
  • 原文地址:https://www.cnblogs.com/chuchudongderen/p/3195655.html
Copyright © 2011-2022 走看看