ORACLE PL/SQL编程总结

Posted 码农_指尖改变世界

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了ORACLE PL/SQL编程总结相关的知识,希望对你有一定的参考价值。

----------异常错误处理---------

即使是写得最好的PL/SQL程序也会遇到错误或未预料到的事件。一个优秀的程序都应该能够正确处理各种出错情况,并尽可能从错误中恢复。任何ORACLE错误(报告为ORA-xxxxx形式的Oracle错误号)、PL/SQL运行错误或用户定义条件(不一写是错误),都可以。当然了,PL/SQL编译错误不能通过PL/SQL异常处理来处理,因为这些错误发生在PL/SQL程序执行之前。

ORACLE 提供异常情况(EXCEPTION)和异常处理(EXCEPTION HANDLER)来实现错误处理。

5.1异常处理概念

异常情况处理(EXCEPTION)是用来处理正常执行过程中未预料的事件,程序块的异常处理预定义的错误和自定义错误,由于PL/SQL程序块一旦产生异常而没有指出如何处理时,程序就会自动终止整个程序运行. 

有三种类型的异常错误:

    1. 预定义 ( Predefined )错误

  ORACLE预定义的异常情况大约有24个。对这种异常情况的处理,无需在程序中定义,由ORACLE自动将其引发。

    2. 非预定义 ( Predefined )错误

   即其他标准的ORACLE错误。对这种异常情况的处理,需要用户在程序中定义,然后由ORACLE自动将其引发。

    3. 用户定义(User_define) 错误

 程序执行过程中,出现编程人员认为的非正常情况。对这种异常情况的处理,需要用户在程序中定义,然后显式地在程序中将其引发。

异常处理部分一般放在 PL/SQL 程序体的后半部,结构为:

EXCEPTION
   WHEN first_exception THEN  <code to handle first exception >
   WHEN second_exception THEN  <code to handle second exception >
   WHEN OTHERS THEN  <code to handle others exception >
END;

异常处理可以按任意次序排列,但 OTHERS 必须放在最后。

 

5.1.1  预定义的异常处理

 

 预定义说明的部分 ORACLE 异常错误

 

错误号

异常错误信息名称

说明

ORA-0001

Dup_val_on_index

         违反了唯一性限制

ORA-0051

Timeout-on-resource

               在等待资源时发生超时

ORA-0061

Transaction-backed-out

               由于发生死锁事务被撤消

ORA-1001

Invalid-CURSOR

               试图使用一个无效的游标

ORA-1012

Not-logged-on

               没有连接到ORACLE

ORA-1017

Login-denied

               无效的用户名/口令

ORA-1403

No_data_found

              SELECT INTO没有找到数据

ORA-1422

Too_many_rows

               SELECT INTO 返回多行

ORA-1476

Zero-divide

               试图被零除

ORA-1722

Invalid-NUMBER

               转换一个数字失败

ORA-6500

Storage-error

               内存不够引发的内部错误

ORA-6501

Program-error

               内部错误

ORA-6502

Value-error

               转换或截断错误

ORA-6504

Rowtype-mismatch

               宿主游标变量与 PL/SQL变 量有不兼容行类型

ORA-6511

CURSOR-already-OPEN

               试图打开一个已处于打开状 态的游标

ORA-6530

Access-INTO-null

               试图为null 对象的属性赋值

ORA-6531

Collection-is-null

               试图将Exists 以外的集合( collection)方法应用于一个null pl/sql 表上或varray上

ORA-6532

Subscript-outside-limit

               对嵌套或varray索引得引用超出声明范围以外

ORA-6533

Subscript-beyond-count

               对嵌套或varray 索引得引用大于集合中元素的个数.

 

 

对这种异常情况的处理,只需在PL/SQL块的异常处理部分,直接引用相应的异常情况名,并对其完成相应的异常错误处理即可。

例1:更新指定员工工资,如工资小于1500,则加100;

DECLARE
   v_empno employees.employee_id%TYPE := &empno;
   v_sal   employees.salary%TYPE;
BEGIN
   SELECT salary INTO v_sal FROM employees WHERE employee_id = v_empno;
   IF v_sal<=1500 THEN 
        UPDATE employees SET salary = salary + 100 WHERE employee_id=v_empno; 
        DBMS_OUTPUT.PUT_LINE(\'编码为\'||v_empno||\'员工工资已更新!\');     
   ELSE
        DBMS_OUTPUT.PUT_LINE(\'编码为\'||v_empno||\'员工工资已经超过规定值!\');
   END IF;
EXCEPTION
   WHEN NO_DATA_FOUND THEN  
      DBMS_OUTPUT.PUT_LINE(\'数据库中没有编码为\'||v_empno||\'的员工\');
   WHEN TOO_MANY_ROWS THEN
      DBMS_OUTPUT.PUT_LINE(\'程序运行错误!请使用游标\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END; 

 

5.1.2  非预定义的异常处理

 

对于这类异常情况的处理,首先必须对非定义的ORACLE错误进行定义。步骤如下:

        1. 在PL/SQL 块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

         2. 将其定义好的异常情况,与标准的ORACLE错误联系起来,使用EXCEPTION_INIT语句:

      PRAGMA EXCEPTION_INIT(<异常情况>, <错误代码>);

         3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

例2:删除指定部门的记录信息,以确保该部门没有员工。

INSERT INTO departments VALUES(50, \'FINANCE\', \'CHICAGO\');

DECLARE
   v_deptno departments.department_id%TYPE := &deptno;
   deptno_remaining EXCEPTION;
   PRAGMA EXCEPTION_INIT(deptno_remaining, -2292);
   /* -2292 是违反一致性约束的错误代码 */
BEGIN
   DELETE FROM departments WHERE department_id = v_deptno;
EXCEPTION
   WHEN deptno_remaining THEN 
      DBMS_OUTPUT.PUT_LINE(\'违反数据完整性约束!\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END;

 

5.1.3 用户自定义的异常处理

 

当与一个异常错误相关的错误出现时,就会隐含触发该异常错误。用户定义的异常错误是通过显式使用 RAISE 语句来触发。当引发一个异常错误时,控制就转向到 EXCEPTION块异常错误部分,执行错误处理代码。

 对于这类异常情况的处理,步骤如下:

    1. 在PL/SQL 块的定义部分定义异常情况:

<异常情况>  EXCEPTION;

    2. RAISE <异常情况>;

    3. 在PL/SQL 块的异常情况处理部分对异常情况做出相应的处理。

例3:更新指定员工工资,增加100;

DECLARE
   v_empno employees.employee_id%TYPE :=&empno;
   no_result  EXCEPTION;
BEGIN
   UPDATE employees SET salary = salary+100 WHERE employee_id = v_empno;
   IF SQL%NOTFOUND THEN
      RAISE no_result;
   END IF;
EXCEPTION
   WHEN no_result THEN 
      DBMS_OUTPUT.PUT_LINE(\'你的数据更新语句失败了!\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END;

 

5.1.4  用户定义的异常处理

 

调用DBMS_STANDARD(ORACLE提供的包)包所定义的RAISE_APPLICATION_ERROR过程,可以重新定义异常错误消息,它为应用程序提供了一种与ORACLE交互的方法。

RAISE_APPLICATION_ERROR 的语法如下:

    RAISE_APPLICATION_ERROR(error_number,error_message,[keep_errors] );

    这里的error_number 是从 –20,000 到 –20,999 之间的参数,

    error_message 是相应的提示信息(< 2048 字节),

   keep_errors 为可选,如果keep_errors =TRUE ,则新错误将被添加到已经引发的错误列表中。如果keep_errors=FALSE(缺省),则新错误将替换当前的错误列表。

例4:定义触发器,使用RAISE_APPLICATION_ERROR阻止没有员工姓名的新员式记录插入:

CREATE OR REPLACE TRIGGER tr_insert_emp
BEFORE INSERT ON employees
FOR EACH ROW
BEGIN
  IF :new.first_name IS NULL OR :new.last_name is null THEN
    RAISE_APPLICATION_ERROR(-20000,\'Employee must have a name.\');
  END IF;
END;

 

5.2 异常错误传播

由于异常错误可以在声明部分和执行部分以及异常错误部分出现,因而在不同部分引发的异常错误也不一样。

5.2.1  在执行部分引发异常错误

 

当一个异常错误在执行部分引发时,有下列情况:

l 如果当前块对该异常错误设置了处理,则执行它并成功完成该块的执行,然后控制转给包含块。

l 如果没有对当前块异常错误设置定义处理器,则通过在包含块中引发它来传播异常错误。然后对该包含块执行步骤1)。

 

5.2.2  在声明部分引发异常错误

如果在声明部分引起异常情况,即在声明部分出现错误,那么该错误就能影响到其它的块。比如在有如下的PL/SQL程序:

DECLARE
    name varchar2(12):=\'EricHu\';
    其它语句
BEGIN
    其它语句
EXCEPTION
    WHEN OTHERS THEN 
    其它语句
END;

 

        例子中,由于Abc number(3)=’abc’; 出错,尽管在EXCEPTION中说明了WHEN OTHERS THEN语句,但WHEN OTHERS THEN也不会被执行。 但是如果在该错误语句块的外部有一个异常错误,则该错误能被抓住,如:

BEGIN
    DECLARE
    name varchar2(12):=\'EricHu\';
    其它语句
   BEGIN
    其它语句
   EXCEPTION
    WHEN OTHERS THEN 
    其它语句
    END;
EXCEPTION
WHEN OTHERS THEN 
    其它语句
END;

 

5.3 异常错误处理编程

       在一般的应用处理中,建议程序人员要用异常处理,因为如果程序中不声明任何异常处理,则在程序运行出错时,程序就被终止,并且也不提示任何信息。下面是使用系统提供的异常来编程的例子。

 

5.4  在 PL/SQL 中使用 SQLCODE,SQLERRM异常处理函数

 

       由于ORACLE 的错信息最大长度是512字节,为了得到完整的错误提示信息,我们可用 SQLERRM和 SUBSTR 函数一起得到错误提示信息,方便进行错误,特别是如果WHEN OTHERS异常处理器时更为方便。

SQLCODE  返回遇到的Oracle错误号,

SQLERRM  返回遇到的Oracle错误信息.

如:  SQLCODE=-100   è SQLERRM=’no_data_found ‘

 SQLCODE=0      è SQLERRM=’normal, successfual completion’

例1:将ORACLE错误代码及其信息存入错误代码表

CREATE TABLE errors (errnum NUMBER(4), errmsg VARCHAR2(100));

DECLARE
   err_msg  VARCHAR2(100);
BEGIN
   /*  得到所有 ORACLE 错误信息  */
   FOR err_num IN -100 .. 0 LOOP
      err_msg := SQLERRM(err_num);
      INSERT INTO errors VALUES(err_num, err_msg);
   END LOOP;
END;
DROP TABLE errors;

 

例2:查询ORACLE错误代码;

BEGIN
   INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id)
   VALUES(2222, \'Eric\',\'Hu\', SYSDATE, 20);
   DBMS_OUTPUT.PUT_LINE(\'插入数据记录成功!\');
   
   INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id)
   VALUES(2222, \'胡\',\'勇\', SYSDATE, 20);
   DBMS_OUTPUT.PUT_LINE(\'插入数据记录成功!\');
EXCEPTION
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END;

 

例3: 利用ORACLE错误代码,编写异常错误处理代码;

DECLARE
   empno_remaining EXCEPTION;
   PRAGMA EXCEPTION_INIT(empno_remaining, -1);
   /* -1 是违反唯一约束条件的错误代码 */
BEGIN
   INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id)
   VALUES(3333, \'Eric\',\'Hu\', SYSDATE, 20);
   DBMS_OUTPUT.PUT_LINE(\'插入数据记录成功!\');
   
   INSERT INTO employees(employee_id, first_name,last_name,hire_date,department_id)
   VALUES(3333, \'胡\',\'勇\',SYSDATE, 20);
   DBMS_OUTPUT.PUT_LINE(\'插入数据记录成功!\');
EXCEPTION
   WHEN empno_remaining THEN 
      DBMS_OUTPUT.PUT_LINE(\'违反数据完整性约束!\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END;

 

***********************************************

-----------把过程与函数说透-----------

 

 6.1 引言

 

过程与函数(另外还有包与触发器)是命名的PL/SQL块(也是用户的方案对象),被编译后存储在数据库中,以备执行。因此,其它PL/SQL块可以按名称来使用他们。所以,可以将商业逻辑、企业规则写成函数或过程保存到数据库中,以便共享。

过程和函数统称为PL/SQL子程序,他们是被命名的PL/SQL块,均存储在数据库中,并通过输入、输出参数或输入/输出参数与其调用者交换信息。过程和函数的唯一区别是函数总向调用者返回数据,而过程则不返回数据。在本节中,主要介绍:

      1.   创建存储过程和函数。

      2.   正确使用系统级的异常处理和用户定义的异常处理。

      3.   建立和管理存储过程和函数。

 

 

6.2 创建函数

1. 创建函数(语法如下:)

 

CREATE [OR REPLACEFUNCTION function_name
 (arg1 [ { IN OUT IN OUT }] type1 [DEFAULT value1],
 [arg2 [ { IN OUT IN OUT }] type2 [DEFAULT value1]],
 ......
 [argn [ { IN OUT IN OUT }] typen [DEFAULT valuen]])
 [ AUTHID DEFINER | CURRENT_USER ]
RETURN return_type
 IS AS
    <类型.变量的声明部分>
BEGIN
    执行部分
    RETURN expression
EXCEPTION
    异常处理部分
END function_name;

 

l         IN,OUT,IN OUT是形参的模式。若省略,则为IN模式。IN模式的形参只能将实参传递给形参,进入函数内部,但只能读不能写,函数返回时实参的值不变。OUT模式的形参会忽略调用时的实参值(或说该形参的初始值总是NULL),但在函数内部可以被读或写,函数返回时形参的值会赋予给实参。IN OUT具有前两种模式的特性,即调用时,实参的值总是传递给形参,结束时,形参的值传递给实参。调用时,对于IN模式的实参可以是常量或变量,但对于OUT和IN OUT模式的实参必须是变量。

  l         一般,只有在确认function_name函数是新函数或是要更新的函数时,才使用OR REPALCE关键字,否则容易删除有用的函数。

例子:获取某部门的工资总和:

 

--获取某部门的工资总和
CREATE OR REPLACE
FUNCTION get_salary(
  Dept_no NUMBER,
  Emp_count OUT NUMBER)
  RETURN NUMBER
IS
  V_sum NUMBER;
BEGIN
  SELECT SUM(SALARY), count(*) INTO V_sum, emp_count
    FROM EMPLOYEES WHERE DEPARTMENT_ID=dept_no;
  RETURN v_sum;
EXCEPTION
   WHEN NO_DATA_FOUND THEN
      DBMS_OUTPUT.PUT_LINE(\'你需要的数据不存在!\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(SQLCODE||\'---\'||SQLERRM);
END get_salary;

 

 

 2. 函数的调用

  函数声明时所定义的参数称为形式参数,应用程序调用时为函数传递的参数称为实际参数。应用程序在调用函数时,可以使用以下三种方法向函数传递参数:

  第一种参数传递格式:位置表示法。

  即在调用时按形参的排列顺序,依次写出实参的名称,而将形参与实参关联起来进行传递。用这种方法进行调用,形参与实参的名称是相互独立,没有关系,强调次序才是重要的。

  格式为:

1
argument_value1[,argument_value2 …]

例子:计算某部门的工资总和:

 

DECLARE
  V_num NUMBER;
  V_sum NUMBER;
BEGIN
  V_sum :=get_salary(10, v_num);
  DBMS_OUTPUT.PUT_LINE(\'部门号为:10的工资总和:\'||v_sum||\',人数为:\'||v_num);
END;

 

第二种参数传递格式:名称表示法。

  即在调用时按形参的名称与实参的名称,写出实参对应的形参,而将形参与实参关联起来进行传递。这种方法,形参与实参的名称是相互独立的,没有关系,名称的对应关系才是最重要的,次序并不重要。

  格式为:

1
argument => parameter [,…]

         其中:argument 为形式参数,它必须与函数定义时所声明的形式参数名称相同parameter 为实际参数。

 在这种格式中,形势参数与实际参数成对出现,相互间关系唯一确定,所以参数的顺序可以任意排列。

例子:计算某部门的工资总和:

 

DECLARE
  V_num NUMBER;
    V_sum NUMBER;
BEGIN
    V_sum :=get_salary(emp_count => v_num, dept_no => 10);
    DBMS_OUTPUT.PUT_LINE(\'部门号为:10的工资总和:\'||v_sum||\',人数为:\'||v_num);
END;

 

第三种参数传递格式:组合传递。

即在调用一个函数时,同时使用位置表示法和名称表示法为函数传递参数。采用这种参数传递方法时,使用位置表示法所传递的参数必须放在名称表示法所传递的参数前面。也就是说,无论函数具有多少个参数,只要其中有一个参数使用名称表示法,其后所有的参数都必须使用名称表示法。

 

CREATE OR REPLACE FUNCTION demo_fun(
  Name VARCHAR2,--注意VARCHAR2不能给精度,如:VARCHAR2(10),其它类似
  Age INTEGER,
  Sex VARCHAR2)
  RETURN VARCHAR2
AS
  V_var VARCHAR2(32);
BEGIN
  V_var := name||\':\'||TO_CHAR(age)||\'岁.\'||sex;
  RETURN v_var;
END;
 
DECLARE
  Var VARCHAR(32);
BEGIN
  Var := demo_fun(\'user1\', 30, sex => \'男\');
  DBMS_OUTPUT.PUT_LINE(var);
 
  Var := demo_fun(\'user2\', age => 40, sex => \'男\');
  DBMS_OUTPUT.PUT_LINE(var);
 
  Var := demo_fun(\'user3\', sex => \'女\', age => 20);
  DBMS_OUTPUT.PUT_LINE(var);
END;

 

    无论采用哪一种参数传递方法,实际参数和形式参数之间的数据传递只有两种方法:传址法和传值法。所谓传址法是指在调用函数时,将实际参数的地址指针传递给形式参数,使形式参数和实际参数指向内存中的同一区域,从而实现参数数据的传递。这种方法又称作参照法,即形式参数参照实际参数数据。输入参数均采用传址法传递数据。

传值法是指将实际参数的数据拷贝到形式参数,而不是传递实际参数的地址。默认时,输出参数和输入/输出参数均采用传值法。在函数调用时,ORACLE将实际参数数据拷贝到输入/输出参数,而当函数正常运行退出时,又将输出形式参数和输入/输出形式参数数据拷贝到实际参数变量中。 

  3. 参数默认值

   在CREATE OR REPLACE FUNCTION 语句中声明函数参数时可以使用DEFAULT关键字为输入参数指定默认值。

 

CREATE OR REPLACE FUNCTION demo_fun(
  Name VARCHAR2,
  Age INTEGER,
  Sex VARCHAR2 DEFAULT \'男\')
  RETURN VARCHAR2
AS
  V_var VARCHAR2(32);
BEGIN
  V_var := name||\':\'||TO_CHAR(age)||\'岁.\'||sex;
  RETURN v_var;
END;

    具有默认值的函数创建后,在函数调用时,如果没有为具有默认值的参数提供实际参数值,函数将使用该参数的默认值。但当调用者为默认参数提供实际参数时,函数将使用实际参数值。在创建函数时,只能为输入参数设置默认值,而不能为输入/输出参数设置默认值。

 

DECLARE
 varVARCHAR(32);
BEGIN
 Var := demo_fun(\'user1\', 30);
 DBMS_OUTPUT.PUT_LINE(var);
 Var := demo_fun(\'user2\', age => 40);
 DBMS_OUTPUT.PUT_LINE(var);
 Var := demo_fun(\'user3\', sex => \'女\', age => 20);
 DBMS_OUTPUT.PUT_LINE(var);
END;

 

6.3 存储过程

6.3.1  创建过程

 

建立存储过程

  在 ORACLE SERVER上建立存储过程,可以被多个应用程序调用,可以向存储过程传递参数,也可以向存储过程传回参数.

  创建过程语法:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE [OR REPLACEPROCEDURE procedure_name
([arg1 [ IN OUT IN OUT ]] type1 [DEFAULT value1],
 [arg2 [ IN OUT IN OUT ]] type2 [DEFAULT value1]],
 ......
 [argn [ IN OUT IN OUT ]] typen [DEFAULT valuen])
    [ AUTHID DEFINER | CURRENT_USER ]
IS AS }
  <声明部分>
BEGIN
  <执行部分>
EXCEPTION
  <可选的异常错误处理程序>
END procedure_name;

说明:相关参数说明参见函数的语法说明。

例子:使用存储过程向departments表中插入数据。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
CREATE OR REPLACE
PROCEDURE insert_dept
  (v_dept_id IN departments.department_id%TYPE,
   v_dept_name IN departments.department_name%TYPE,
   v_mgr_id IN departments.manager_id%TYPE,
   v_loc_id IN departments.location_id%TYPE)
IS
   ept_null_error EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_null_error, -1400);
   ept_no_loc_id EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_no_loc_id, -2291);
BEGIN
   INSERT INTO departments
   (department_id, department_name, manager_id, location_id)
   VALUES
   (v_dept_id, v_dept_name, v_mgr_id, v_loc_id);
   DBMS_OUTPUT.PUT_LINE(\'插入部门\'||v_dept_id||\'成功\');
EXCEPTION
   WHEN DUP_VAL_ON_INDEX THEN
      RAISE_APPLICATION_ERROR(-20000, \'部门编码不能重复\');
   WHEN ept_null_error THEN
      RAISE_APPLICATION_ERROR(-20001, \'部门编码、部门名称不能为空\');
   WHEN ept_no_loc_id THEN
      RAISE_APPLICATION_ERROR(-20002, \'没有该地点\');
END insert_dept;
 
/*调用实例一:
DECLARE
   ept_20000 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20000, -20000);
   ept_20001 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20001, -20001);
   ept_20002 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20002, -20002);
BEGIN
   insert_dept(300, \'部门300\', 100, 2400);
   insert_dept(310, NULL, 100, 2400);
   insert_dept(310, \'部门310\', 100, 900);
EXCEPTION
   WHEN ept_20000 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20000部门编码不能重复\');
   WHEN ept_20001 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20001部门编码、部门名称不能为空\');
   WHEN ept_20002 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20002没有该地点\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(\'others出现了其他异常错误\');
END;
 
调用实例二:
DECLARE
   ept_20000 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20000, -20000);
   ept_20001 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20001, -20001);
   ept_20002 EXCEPTION;
   PRAGMA EXCEPTION_INIT(ept_20002, -20002);
BEGIN
   insert_dept(v_dept_name => \'部门310\', v_dept_id => 310,
               v_mgr_id => 100, v_loc_id => 2400);
   insert_dept(320, \'部门320\', v_mgr_id => 100, v_loc_id => 900);
EXCEPTION
   WHEN ept_20000 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20000部门编码不能重复\');
   WHEN ept_20001 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20001部门编码、部门名称不能为空\');
   WHEN ept_20002 THEN
      DBMS_OUTPUT.PUT_LINE(\'ept_20002没有该地点\');
   WHEN OTHERS THEN
      DBMS_OUTPUT.PUT_LINE(\'others出现了其他异常错误\');
END;
*/

 

6.3.2  调用存储过程

 

存储过程建立完成后,只要通过授权,用户就可以在SQLPLUS 、ORACLE开发工具或第三方开发工具中来调用运行。对于参数的传递也有三种:按位置传递、按名称传递和组合传递,传递方法与函数的一样。ORACLE 使用EXECUTE 语句来实现对存储过程的调用: 

EXEC[UTE] procedure_name( parameter1, parameter2…);

例:EXECUTE logexecution;

    在PL/SQL 程序中还可以在块内建立本地函数和过程,这些函数和过程不存储在数据库中,但可以在创建它们的PL/SQL 程序中被重复调用。本地函数和过程在PL/SQL 块的声明部分定义,它们的语法格式与存储函数和过程相同,但不能使用CREATE OR REPLACE 关键字。

例子:建立本地过程,用于计算指定部门的工资总和,并统计其中的职工数量;

 

1
2
3
4
5
6
7
<

以上是关于ORACLE PL/SQL编程总结的主要内容,如果未能解决你的问题,请参考以下文章

oracle PL/SQL高级编程

Oracle | PL/SQL编程

Oracle笔记4-pl/sql-分支/循环/游标/异常/存储/调用/触发器

oracle PL/SQL编程语言之游标的使用

oracle PL/SQL编程语言之游标的使用

Oracle——PL/SQL

(c)2006-2024 SYSTEM All Rights Reserved IT常识