PL/SQL学习汇总

1:介绍

sql是非过程语言,在编程中总是会用到过程化控制,PL/SQL就是提供了过程化控制的语言来弥补SQL语言的这一点缺陷。

PL/SQL 语句在后面的执行中  pl/sql语句由 PL/SQL引擎执行,SQL语句由 sql引擎执行。PL/SQL 集成了过程化与SQL一起使用, 提高了性能,因为一个过程执行完成后,
统一返回结果。减少了数据的传输。如下图所示:

2:PL/SQL块结构

PL/SQL块由四个部分组成;

1:DECLARE(optional)可有可无  用于生命  变量(variables) , 游标(cursors),用户自定义异常( user-defined exceptions)等。

2:BEGIN(mandatory) 必有:begin里面是 SQL 语句和PL/SQL语句

3:EXCEPTION (optional)可选择的,当出现错误的时候执行,

4:END; (mandatory)必有

函数和过程的区别是: function 需要有返回值, 而 procedure 没有返回值

PL/SQL的变量的规则查询官方文档

注意:非空变量和常量必须对其进行初始化,例如:

v_myname varchar2(20) := ‘Hooo’
v_myname varchar2(20) default   ‘HOOO’

关于 %TYPE类型声明

%TYPE  用法:identifier  table.column_name %TYPE

ex:
emp_lname  employees.last_name%TYPE

也可以和声明的变量的名称相同:
balance  NUMBER(7,2);
min_balance  balance%TYPE := 1000;

注意: 关于oracle中的boolean:   boolean 变量可以有三种类型: TRUE,FALSE,NULL

关于绑定变量(又叫session变量)

绑定变量:
和环境相关:
ex:

[sql] view plaincopy

  1. VARIABLE b_emp_salary NUMBER
  2. BEGIN
  3.   select  salary into  :b_emp_salary
  4.   from  employees where  employee_id=178;
  5. END;

PL/SQL支持嵌入块;
ex:
DECLARE
BEGIN
DECLARE
BEGIN
………………..
END;
END;

 

 

3: Cursor 游标

1:oracle FAQ
2:oracle 11g游标介绍

游标是一个指针指向一个私有的内存区,私有内存区被 oracle 服务器分配。

 

 

cursors is a pointer used to fetch rows from a result set. One can think of a cursor as a data structure that describes the results returned from a SQL SELECT statement. One of the variables in this structure is a pointer to the next record to be fetched from the query results.

Note that if you do repetitive stuff inside a loop and you fail to close your cursors, you would soon run into theORA-01000: maximum number of open cursors exceeded error.

游标有两种类型: 隐式游标和显式游标 ,隐式游标: 有oracle服务器进行创建和管理,显式游标: 编程人员要进行声明和创建;

显式游标和隐式游标

游标的属性:
SQL%FOUND  至少一条记录在sql 语句的操作中受到影响
SQL%NOTFOUND 和%FOUND相反
SQL%ROWCOUNT

关于游标需要单独深入研究

4:书写控制结构

1:IF 控制

[sql] view plaincopy

  1. IF condition
  2.    THEN  statements
  3. ELSIF condition
  4.    THEN  statements
  5. ELSE
  6.   statements
  7. END IF;

condition有三种类型 :  TRUE ,FALSE,NULL

验证示例:
[sql] view plaincopy

  1. SQL> declare
  2.   2       v_myage  number;
  3.   3  begin
  4.   4    IF v_myage < 11  THEN
  5.   5            DBMS_OUTPUT.PUT_LINE(‘I am a child !’);
  6.   6    ELSE
  7.   7            DBMS_OUTPUT.PUT_LINE(‘I am not a a child’);
  8.   8    END IF;
  9.   9  END;
  10.  10  /
  11. PL/SQL 过程已成功完成。
  12. SQL> set serveroutput on
  13. SQL> /
  14. I am not a a child
  15. PL/SQL 过程已成功完成。

初始化时为null:

[sql] view plaincopy

  1. SQL> declare
  2.   2       v_myage  number;
  3.   3  begin
  4.   4    IF v_myage IS NULL  THEN
  5.   5            DBMS_OUTPUT.PUT_LINE(‘I am a child !’);
  6.   6    ELSE
  7.   7            DBMS_OUTPUT.PUT_LINE(‘I am not a a child’);
  8.   8    END IF;
  9.   9  END;
  10.  10  /
  11. I am a child !
  12. PL/SQL 过程已成功完成。

2:CASE

[sql] view plaincopy

  1. CASE selector
  2.     WHEN  expression1  THEN  result1
  3.     WHEN  expression2  THEN  result2
  4.     ………
  5.     WHEN  expressionN  THEN  resultN
  6.     [ELSE resultN+1]
  7. END;

简单的一个例子:

[sql] view plaincopy

  1. SQL> SET VERIFY OFF
  2. SQL> DECLARE
  3.   2     v_grade  CHAR(1) := UPPER(‘&grade’);
  4.   3     v_appraisal VARCHAR2(20);
  5.   4
  6.   5  BEGIN
  7.   6      v_appraisal := CASE v_grade
  8.   7            WHEN  ‘A’ THEN  ‘Excellent’
  9.   8            WHEN  ‘B’  THEN ‘Very Good’
  10.   9            WHEN  ‘C’  THEN  ‘Good’
  11.  10            ELSE ‘NO such grde’
  12.  11  END;
  13.  12  DBMS_OUTPUT.PUT_LINE(‘Grade: ‘|| v_grade || ‘  Apprasisal ‘ || v_appraisal)
  14. ;
  15.  13  END;
  16.  14  /
  17. 输入 grade 的值:  A
  18. Grade: A  Apprasisal Excellent
  19. PL/SQL 过程已成功完成。

第二种 CASE  同样的例子比较一下,第二种CASE没有选择符 WHEN后面直接加判断即可
有时候需要判断多个字段时候,比较灵活。

[sql] view plaincopy

  1. SQL> DECLARE
  2.   2     v_grade  CHAR(1) := UPPER(‘&grade’);
  3.   3     v_appraisal VARCHAR2(20);
  4.   4
  5.   5  BEGIN
  6.   6      v_appraisal := CASE
  7.   7            WHEN  v_grade = ‘A’ THEN  ‘Excellent’
  8.   8            WHEN  v_grade IN (‘B’,’C’)  THEN ‘Very Good’
  9.   9
  10.  10            ELSE ‘NO such grde’
  11.  11  END;
  12.  12  DBMS_OUTPUT.PUT_LINE(‘Grade: ‘|| v_grade || ‘  Apprasisal ‘ || v_appraisal)
  13. ;
  14.  13  END;
  15.  14  /
  16. 输入 grade 的值:  B
  17. Grade: B  Apprasisal Very Good
  18. PL/SQL 过程已成功完成。

以上是CASE的表达式的介绍

下面介绍CASE 语句;
CASE
END CASE;
在CASE语句中 要注意用END CASE结尾;

CASE表达式和CASE语句的区别:  表达式可以赋值
CASE语句是一个语句,不能再赋值给其他结果了,CASE语句需要用 END CASE结尾;

几个注意事项:
if  a and b
或者 if  a or b
应该把比较好运算的,耗内存比较少的,放在a位置,
因为 a先计算,对于 and来说 a为false 后面的b就不用计算了,
节省了指令和内存。
同or a为true时一样。
使用null可以增强程序的可读性:
if condition
then
else
then  null;
[sql] view plaincopy

  1. null的另一个用法:
  2. DECLARE
  3.   …..
  4.   BEGIN
  5.      IF  condition  then goto lastpoint END IF;
  6.      …….
  7.  <<lastpoint>>  –这个标签后必须有语句,所以 可以用null来表示。
  8.         null;
  9.    END;

3:循环控制

PL/SQL中有三种循环:
BASIC LOOP
FOR  LOOP
WHILE LOOP
1:基本循环:
[sql] view plaincopy

  1. LOOP
  2.   statement1;
  3.   EXIT  [WHEN condition];
  4. END LOOP

EXIT相当于 其他语言的break;

2:While 循环:
[sql] view plaincopy

  1. WHILE condition LOOP
  2.      statement1;
  3.      statement2;
  4. ……
  5. END LOOP;

3:FOR循环;

[sql] view plaincopy

  1. FOR counter  IN [REVERSE]–REVERSE代表倒过来
  2.      lover_bound…upper_bound LOOP
  3.   statement1;
  4.   statement2;
  5.   …………
  6. END LOOP;
  7. <span style=”color:#cc0000;”>FOR循环的步长必须是1。</span>

11g版本 增加了continue关键字,这个和java中的continue用法一致。
continue 和 exit的语法一致。
三种方式。
exit ;
exit when condition;
exit  标签 when condition; 退出到标签为位置。

例子:
[sql] view plaincopy

  1. SQL> DECLARE
  2.   2     v_total NUMBER :=0;
  3.   3  BEGIN
  4.   4    <<BeforeTopLoop>>
  5.   5    FOR  i  IN  1..10  LOOP
  6.   6      v_total := v_total+1;
  7.   7      DBMS_OUTPUT.PUT_LINE(‘Total is:’ || v_total);
  8.   8     FOR j  in 1..10 LOOP
  9.   9         CONTINUE BeforeTopLoop  WHEN i+j > 5;
  10.  10         v_total := v_total +1;
  11.  11     END LOOP;
  12.  12    END LOOP;
  13.  13  END;
  14.  14  /
  15. Total is:1
  16. Total is:6
  17. Total is:10
  18. Total is:13
  19. Total is:15
  20. Total is:16
  21. Total is:17
  22. Total is:18
  23. Total is:19
  24. Total is:20
  25. PL/SQL 过程已成功完成。

4:GOTO 语句:

语法:  GOTO  label_name;

[sql] view plaincopy

  1. SQL> BEGIN
  2.   2    GOTO second_output;
  3.   3    DBMS_OUTPUT.PUT_LINE(‘This line will never execute.’);
  4.   4    <<second_output>>
  5.   5    DBMS_OUTPUT.PUT_LINE(‘We are here!’);
  6.   6   END;
  7.   7   /
  8. We are here!
  9. PL/SQL 过程已成功完成。

以上语句第一个输出永远不被执行。

5:复合数据类型

两种复合数据类型:  collections 和 records
集合和记录的区别:
记录中存储不同的数据类型,而集合中存储相同的数据类型。
记录相当于java语言中的实体类.
集合相当于数组,java的集合的底层都是采用数组实现的。

1:创建PL/SQL Record 语法:

[sql] view plaincopy

  1. 记录声明;
  2. TYPE type_name IS RECORD
  3.     (field_declaration[,field_declaration]……);
  4.  identifier type_name;
  5. 域的声明
  6. field_declaration;
  7.     field_name { field_type|variable%TYPE| table.column%TYPE|table%ROWTYPE}
  8.     [[NOT NULL]{:= | DEFAULT} expr]
  9.     }

2:%ROWTYPE类型

[sql] view plaincopy

  1. SQL> DECLARE
  2.   2        person employees%ROWTYPE;
  3.   3  BEGIN
  4.   4        select * INTO person FROM employees WHERE  employee_id = 100;
  5.   5       DBMS_OUTPUT.PUT_LINE(‘Name: ‘||person.first_name);
  6.   6  END;
  7.   7  /
  8. Name: Steven
  9. PL/SQL 过程已成功完成。

%TYPE %ROWTYPE 都是采用 锚锁定技术,
锚引用是在编译期间解析,如果数据变量类型或者表结构列类型以及列数
发生改变, 含有 %TYPE %ROWTYPE  的代码要重新进行编译。

关于锚声明的一些了解:

相当于 A—->B  A引用B B被改变了,要进行重新编译,保持同步。

两个很好的例子:
使用 %ROWTYPE
[sql] view plaincopy

  1. 首先创建表:
  2. SQL> create table retired_emps(empno number(6),ename varchar(25),job varchar(10)
  3. ,mgr number(6) , hiredate date,leavedate date,sal number(8,2),comm number(2,2),d
  4. eptno number(4));
  5. 表已创建。
[sql] view plaincopy

  1. SQL> select * from  retired_emps;
  2. 未选定行
  3. SQL> DECLARE
  4.   2     v_employee_number number :=124;
  5.   3     v_emp_rec  retired_emps%ROWTYPE;
  6.   4
  7.   5    BEGIN
  8.   6     SELECT employee_id,last_name,job_id,manager_id,
  9.   7     hire_date,sysdate,salary,commission_pct,department_id INTO
  10.   8     v_emp_rec FROM employees WHERE  employee_id = v_employee_number;
  11.   9     INSERT INTO retired_emps VALUES v_emp_rec;
  12.  10    END;
  13.  11    /
  14. PL/SQL 过程已成功完成。
  15. SQL>  select * from  retired_emps;
  16.      EMPNO ENAME                     JOB               MGR HIREDATE
  17. ———- ————————- ———- ———- ————–
  18. LEAVEDATE             SAL       COMM     DEPTNO
  19. ————– ———- ———- ———-
  20.        124 Mourgos                   ST_MAN            100 16-11月-99
  21. 08-6月 -13           5800                    50

更新的时候也可以使用 都是一样

例如: UPDATE retired_emps  set row = v_emp_rec where empno= v_employee_number;
例子: 一个例子说明了三种方式;
这个例子说明了 通过一个表的列声明 ROWTYPE
通过显式游标声明,
通过 TYPE 直接声明三种方式 。

[sql] view plaincopy

  1. create table cust_sales_roundup(
  2.      customer_id NUMBER(5),
  3.      customer_name VARCHAR2(100),
  4.      total_sales NUMBER(15,2)
  5.    );
[sql] view plaincopy

  1. SQL> DECLARE
  2.   2        cust_sales_roundup_rec  cust_sales_roundup%ROWTYPE;
  3.   3        CURSOR cust_sales_cur is SELECT * FROM cust_sales_roundup;
  4.   4        cust_sales_rec cust_sales_cur % ROWTYPE;
  5.   5
  6.   6        TYPE  customer_sales_rectype is RECORD
  7.   7        (
  8.   8          customer_id NUMBER(5),
  9.   9             customer_name cust_sales_roundup.customer_name%TYPE,
  10.  10                     total_sales NUMBER(15,2)
  11.  11        );
  12.  12
  13.  13        prefererred_cust_rec customer_sales_rectype;
  14.  14
  15.  15   BEGIN
  16.  16     –Assign one recored to another
  17.  17     cust_sales_roundup_rec := cust_sales_rec;
  18.  18     prefererred_cust_rec := cust_sales_rec;
  19.  19   END;
  20.  20   /
  21. PL/SQL 过程已成功完成。

3:关联数组

关联数组是PL/SQL集合,有两列:
Key  Values
               key: 可以是 integer和 string数据类型
values:是一个scalar标量 或者 record
关联数组的顺序:
如何定义关联数组:
[sql] view plaincopy

  1. TYPE  type_name  IS TABLE OF
  2.          { column_type | variable%TYPE
  3.          |table.column%TYPE} [NOT NULL]
  4.          |INDEX BY PLS_INTEGER | BINARY_INTEGER
  5.           |VARCHAR2(<size>);
  6.        }
  7.   identifier type_name;

1:ex: 一个很综合的例子:  说明:

happyfamily.FIRST 第一个索引
happyfamily.NEXT 下一个索引
happyfamily.EXISTS(key) 判断key是否存在。

[sql] view plaincopy

  1. SQL> DECLARE
  2.   2     TYPE  list_of_names_t IS TABLE OF   employees.first_name%TYPE
  3.   3           INDEX BY PLS_INTEGER;
  4.   4     happyfamily list_of_names_t;
  5.   5     l_row PLS_INTEGER;
  6.   6
  7.   7  BEGIN
  8.   8     happyfamily(2020202) := ‘topwqp’;
  9.   9     happyfamily(-15070) := ‘Steven’;
  10.  10     happyfamily(-90900) :=’Chris’;
  11.  11     happyfamily(88) := ‘Veva’;
  12.  12
  13.  13     l_row := happyfamily.FIRST;
  14.  14     WHILE(l_row IS NOT NULL)
  15.  15     LOOP
  16.  16       DBMS_OUTPUT.PUT_LINE(l_row || ‘–>’ || happyfamily(l_row));
  17.  17       l_row := happyfamily.NEXT(l_row);
  18.  18     END LOOP;
  19.  19
  20.  20      l_row := 88;
  21.  21
  22.  22      IF  happyfamily.EXISTS(l_row) THEN
  23.  23           DBMS_OUTPUT.PUT_LINE(‘It is here!—->’ || happyfamily(l_row));
  24.  24      ELSE
  25.  25           DBMS_OUTPUT.PUT_LINE(‘It is not here !—->’|| happyfamily(l_row))
  26. ;
  27.  26      END IF;
  28.  27  END;
  29.  28  /
  30. -90900–>Chris
  31. -15070–>Steven
  32. 88–>Veva
  33. 2020202–>topwqp
  34. It is here!—->Veva
  35. PL/SQL 过程已成功完成。

关联数组相关的方法:

EXISTS  PRIOR  COUNT NEXT FIRST DELETE  LAST
这些方法需要自己查PL/SQL推荐的书籍学习。

2: ex2:关联数组的使用:这也是一个很好的例子:

[sql] view plaincopy

  1. SQL>  DECLARE
  2.   2         TYPE  emp_table_type IS TABLE OF
  3.   3         employees%ROWTYPE  INDEX BY PLS_INTEGER;
  4.   4        my_emp_table  emp_table_type;
  5.   5        max_count NUMBER(3) := 104;
  6.   6  BEGIN
  7.   7      FOR i IN  100..max_count
  8.   8      LOOP
  9.   9         SELECT * INTO my_emp_table(i) FROM employees
  10.  10              WHERE employee_id = i;
  11.  11      END LOOP;
  12.  12
  13.  13      FOR i IN my_emp_table.FIRST..my_emp_table.LAST
  14.  14      LOOP
  15.  15      DBMS_OUTPUT.PUT_LINE(my_emp_table(i).last_name);
  16.  16      END LOOP;
  17.  17  END;
  18.  18  /
  19. King
  20. Kochhar
  21. De Haan
  22. Hunold
  23. Ernst
  24. PL/SQL 过程已成功完成。

3:关于key为string的关联数组的使用:

 这个例子也很具有典型性;可以运行下:
[sql] view plaincopy

  1. SQL> DECLARE
  2.   2       SUBTYPE location_t IS VARCHAR2(64);
  3.   3       TYPE population_type IS TABLE OF NUMBER INDEX BY location_t;
  4.   4
  5.   5       l_country_population  population_type;
  6.   6       l_count PLS_INTEGER;
  7.   7       l_location location_t;
  8.   8  BEGIN
  9.   9        l_country_population(‘Greeland’) := 100000;
  10.  10        l_country_population(‘USA’) := 3000000000;
  11.  11        l_country_population(‘Iceland’) := 750000;
  12.  12        l_country_population(‘Australia’) := 230000000;
  13.  13        l_country_population(‘usa’) := 40000000;
  14.  14
  15.  15        l_count := l_country_population.COUNT;
  16.  16        DBMS_OUTPUT.PUT_LINE(‘COUNT=’||l_count);
  17.  17
  18.  18        l_location := l_country_population.FIRST;
  19.  19        DBMS_OUTPUT.PUT_LINE(‘First Row =’||l_location);
  20.  20        DBMS_OUTPUT.PUT_LINE(‘First Value=’||l_country_population(l_location)
  21. );
  22.  21
  23.  22        l_location := l_country_population.LAST;
  24.  23        DBMS_OUTPUT.PUT_LINE(‘LAST Row =’||l_location);
  25.  24        DBMS_OUTPUT.PUT_LINE(‘LAST Value=’||l_country_population(l_location))
  26. ;
  27.  25  END;
  28.  26  /
  29. COUNT=5
  30. First Row =Australia
  31. First Value=230000000
  32. LAST Row =usa
  33. LAST Value=40000000
  34. PL/SQL 过程已成功完成。

4:嵌套表

5:显式游标

语法:
CURSOR cursor_name is  select statement;
显式游标的执行流程:
ex:  演示执行一下:
[sql] view plaincopy

  1. SQL> DECLARE
  2.   2   CURSOR c_emp_cursor IS
  3.   3    SELECT employee_id, last_name FROM employees
  4.   4    WHERE  department_id =30;
  5.   5    v_emp_record c_emp_cursor%ROWTYPE;
  6.   6  BEGIN
  7.   7      OPEN  c_emp_cursor;
  8.   8      LOOP
  9.   9       FETCH c_emp_cursor INTO v_emp_record;
  10.  10       EXIT WHEN c_emp_cursor%NOTFOUND;
  11.  11       DBMS_OUTPUT.PUT_LINE(v_emp_record.employee_id ||’  ‘ ||v_emp_record.la
  12. st_name);
  13.  12     END LOOP;
  14.  13     CLOSE c_emp_cursor;
  15.  14  END;
  16.  15  /
  17. 114  Raphaely
  18. 115  Khoo
  19. 116  Baida
  20. 117  Tobias
  21. 118  Himuro
  22. 119  Colmenares
  23. PL/SQL 过程已成功完成。

另一种变种:很简单的形式:

[sql] view plaincopy

  1. SQL> BEGIN
  2.   2    FOR  i IN (SELECT employee_id,last_name FROM employees WHERE department_i
  3. d =30 )
  4.   3    LOOP
  5.   4    DBMS_OUTPUT.PUT_LINE(i.employee_id ||’—->’||i.last_name);
  6.   5    END LOOP;
  7.   6  END;
  8.   7  /
  9. 114—->Raphaely
  10. 115—->Khoo
  11. 116—->Baida
  12. 117—->Tobias
  13. 118—->Himuro
  14. 119—->Colmenares
  15. PL/SQL 过程已成功完成。

游标的属性:

%ISOPEN

%NOTFOUND

%FOUND

%ROWCOUNT 不是固定值,随着fetch的次数的增加而增加;

通过这个可以写如下语句判断fetch的装载次数:
EXIT WHEN c_emp_cursor%ROWCOUNT > 10 OR  c_emp_cursor %NOTFOUND;

6:带参数的游标:

BULK COLLECT 把查询结果批量导入到集合
例子1:用数组

[sql] view plaincopy

  1. SQL> DECLARE
  2.   2       TYPE emp_type IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER;
  3.   3       l_emp emp_type;
  4.   4       l_row PLS_INTEGER;
  5.   5  BEGIN
  6.   6      SELECT * BULK COLLECT INTO l_EMP FROM employees;
  7.   7      DBMS_OUTPUT.PUT_LINE(‘The count is: ‘|| l_emp.COUNT);
  8.   8      l_row := l_emp.FIRST;
  9.   9      WHILE(l_row IS NOT NULL)
  10.  10      LOOP
  11.  11        DBMS_OUTPUT.PUT_LINE(l_row || ‘:’||l_emp(l_row).employee_id||’—->’|
  12. |l_emp(l_row).first_name);
  13.  12        l_row:=l_emp.NEXT(l_row);
  14.  13       END LOOP;
  15.  14  END;
  16.  15  /
  17. The count is: 107
  18. 1:198—->Donald
  19. 2:199—->Douglas
  20. 3:200—->Jennifer
  21. 4:201—->Michael
  22. 5:202—->Pat
  23. 6:203—->Susan
  24. 7:204—->Hermann
  25. 8:205—->Shelley
  26. 9:206—->William
  27. 10:100—->Steven
  28. 11:101—->Neena
  29. 12:102—->Lex
  30. 13:103—->Alexander
  31. 14:104—->Bruce
  32. 15:105—->David
  33. 16:106—->Valli
  34. 17:107—->Diana
  35. 18:108—->Nancy
  36. 19:109—->Daniel
  37. 20:110—->John
  38. 21:111—->Ismael
  39. 22:112—->Jose Manuel
  40. 23:113—->Luis
  41. 24:114—->Den
  42. 25:115—->Alexander
  43. 26:116—->Shelli
  44. 27:117—->Sigal
  45. 28:118—->Guy
  46. 29:119—->Karen
  47. 30:120—->Matthew
  48. 31:121—->Adam
  49. 32:122—->Payam
  50. 33:123—->Shanta
  51. 34:124—->Kevin
  52. 35:125—->Julia
  53. 36:126—->Irene
  54. 37:127—->James
  55. 38:128—->Steven
  56. 39:129—->Laura
  57. 40:130—->Mozhe
  58. 41:131—->James
  59. 42:132—->TJ
  60. 43:133—->Jason
  61. 44:134—->Michael
  62. 45:135—->Ki
  63. 46:136—->Hazel
  64. 47:137—->Renske
  65. 48:138—->Stephen
  66. 49:139—->John
  67. 50:140—->Joshua
  68. 51:141—->Trenna
  69. 52:142—->Curtis
  70. 53:143—->Randall
  71. 54:144—->Peter
  72. 55:145—->John
  73. 56:146—->Karen
  74. 57:147—->Alberto
  75. 58:148—->Gerald
  76. 59:149—->Eleni
  77. 60:150—->Peter
  78. 61:151—->David
  79. 62:152—->Peter
  80. 63:153—->Christopher
  81. 64:154—->Nanette
  82. 65:155—->Oliver
  83. 66:156—->Janette
  84. 67:157—->Patrick
  85. 68:158—->Allan
  86. 69:159—->Lindsey
  87. 70:160—->Louise
  88. 71:161—->Sarath
  89. 72:162—->Clara
  90. 73:163—->Danielle
  91. 74:164—->Mattea
  92. 75:165—->David
  93. 76:166—->Sundar
  94. 77:167—->Amit
  95. 78:168—->Lisa
  96. 79:169—->Harrison
  97. 80:170—->Tayler
  98. 81:171—->William
  99. 82:172—->Elizabeth
  100. 83:173—->Sundita
  101. 84:174—->Ellen
  102. 85:175—->Alyssa
  103. 86:176—->Jonathon
  104. 87:177—->Jack
  105. 88:178—->Kimberely
  106. 89:179—->Charles
  107. 90:180—->Winston
  108. 91:181—->Jean
  109. 92:182—->Martha
  110. 93:183—->Girard
  111. 94:184—->Nandita
  112. 95:185—->Alexis
  113. 96:186—->Julia
  114. 97:187—->Anthony
  115. 98:188—->Kelly
  116. 99:189—->Jennifer
  117. 100:190—->Timothy
  118. 101:191—->Randall
  119. 102:192—->Sarah
  120. 103:193—->Britney
  121. 104:194—->Samuel
  122. 105:195—->Vance
  123. 106:196—->Alana
  124. 107:197—->Kevin
  125. PL/SQL 过程已成功完成。

例子2: 用游标

[sql] view plaincopy

  1. DECLARE
  2.      CURSOR  ee IS  SELECT * FROM employees;
  3.      TYPE emp_type IS TABLE OF ee%ROWTYPE INDEX BY PLS_INTEGER;
  4.      l_emp emp_type;
  5.      l_row PLS_INTEGER;
  6. BEGIN
  7.     OPEN ee;
  8.     FETCH ee BULK COLLECT INTO l_emp;
  9.     CLOSE ee;
  10.     DBMS_OUTPUT.PUT_LINE(‘The count is: ‘|| l_emp.COUNT);
  11.     l_row := l_emp.FIRST;
  12.     WHILE(l_row IS NOT NULL)
  13.     LOOP
  14.       DBMS_OUTPUT.PUT_LINE(l_row || ‘:’||l_emp(l_row).employee_id||’—->’||l_emp(l_row).first_name);
  15.       l_row:=l_emp.NEXT(l_row);
  16.      END LOOP;
  17. END;

标签