PL/SQL之基础篇
1.PL/SQL概述
PL/SQL(Procedure Language/Structuer Query Language)是Oracle对标准SQL规范的扩展,全面支持SQL的数据操作、事务控制等。PL/SQL完全支持SQL数据类型,减少了在应用程序和数据库之间转换数据的操作。
构成PL/SQL程序的基本单位是程序块。程序块由过程、函数和无名块3种形式组成,它们之间可以互相嵌套。
PL/SQL的运行工具有:SQL*Plus、PL/SQL developer
2.PL/SQL结构
2.1PL/SQL程序块
PL/SQL程序块分为无名块、命名块两种。无名块指未命名的程序块,命名块指过程、函数、包和触发器等。
PL/SQL块由3个部分组成:定义部分、执行部分、异常处理部分。PL/SQL块的基本结构如下:
--DECLARE与EXCEPTION是可选的
[DECLARE
--定义部分]
BEGIN
--执行部分
[EXCEPTION
--异常处理部分]
END;
Notice:DECLARE、BEGIN、EXCEPTION后面没有分号,而END后则必须要带有分号
下面是一个PL/SQL块的一个示例:
SQL> set serveroutput on
SQL> DECLARE
2 a NUMBER;
3 BEGIN
4 a:=1+2;
5 DBMS_OUTPUT.PUT_LINE('1+2='||a);
6 EXCEPTION
7 WHEN OTHERS THEN
8 DBMS_OUTPUT.PUT_LINE('出现异常');
9 END;
10 /
1+2=3 PL/SQL 过程已成功完成。
3.变量的数据类型
按个人的理解,在PL/SQL中,变量的数据类型可以按影响的行列来划分成以下四种类型:单行单列数据类型、单行多列数据类型、多行单列数据类型、多行多列类型。
在分别详细介绍了各种变量的数据类型的使用之前,先看一下变量声明的语法格式:
variable_name [CONSTANT] data_type NOT_NULL [DEFAULT|:=value];
3.1单行单列数据类型
单行单列数据类型也称为标量(scalar)数据类型。
标量数据类型大致可以分为以下四类:
- Number
- Charater
- Data/Time
- Boolean
表3.1显示的为Number类型,表3.2显示的为Charater类型,表3.3显示的是Data/Time及Boolean类型
Datatype | description | Subtypes | description |
BINARY_INTEGER |
用于存储单字节整数。 要求存储长度低于 NUMBER值 |
NATURAL | 用于非负数 |
NATURALN | 只用于非负数和非NULL值 | ||
POSITIVE | 只用于正数 | ||
POSITIVEN | 只用于正数,不能用于NULL值 | ||
SIGNTYPE | 只有值:-1,0或1 | ||
NUMBER |
存储数字值,包括 整数和浮点数。可以 选择精度和刻度方式 语法: number[([,])] |
DECIMAL(DEC) | 小数 |
DOUBLE PRECISION | 双精度小数 | ||
FLOAT | 单精度小数 | ||
INTEGER(INT) | 整数 | ||
NUMERIC | 与NUMBER等价 | ||
REAL | 与NUMBER等价 | ||
SMALLINT | 取值范围比INT小 | ||
PLS_INTEGER |
表示一个有符号整数 范围:-231到231 运算比NUMBER和 BINARY_INTEGER 都快 |
Datatype | rage | subtypes | description |
CHAR | 最大长度32767字节 | CHARACTER | 存储定长字符串,如果长度没有确定,缺省是1 |
LONG | 最大长度2147483647字节 | 存储可变长度字符串 | |
RAW | 最大长度32767字节 | 用于存储二进制数据和字节字符串,当在两个数据库之间时行传递时,RAW数据不在字符集之间进行转换 | |
LONGRAW | 最大长度2147483647字节 | 与LONG数据类型相似,同样他也不能在字符集之间进行转换 | |
ROWID | 18字节 | 与数据库ROWID伪列类型相同,能够存储一个行标示符,可以将行标示符看作数据库中每一行的唯一键值。 | |
VARCHAR2 | 最大长度32767字节 | 与VARCHAR数据类型相似,存储可变长度的字符串。声明方法与VARCHAR相同 |
Datatype | rang | description |
BOOLEAN | TRUE/FALSE | 存储逻辑值TRUE或FALSE |
DATE | 01/01/4712 BC | 存储固定长的日期和时间值 |
在PL/SQL中,除了能使用上面说到的数据类型来声明单行单列变量之外,还可以使用%TYPE变量来声明单行单列变量.
使用%TYPE声明的变量类型与数据表中字段的数据类型相同,当数据表中字段数据类型修改后,PL/SQL程序中相应变量的类型也自动随之改变.如:
v_name emp.ename%TYPE;
3.2单行多列数据类型
3.2.1 %ROWTYPE变量
%ROWTYPE变量用来存储一行数据.如下面使用%ROWTYPE类型的变量存储DEPT表中的一行数据:
set serveroutput on
DECLARE
v_dept dept%ROWTYPE;
BEGIN
SELECT * into v_dept FROM dept WHERE deptno=30;
DBMS_OUTPUT.PUT_LINE(v_dept.deptno);
DBMS_OUTPUT.PUT_LINE(v_dept.dname);
DBMS_OUTPUT.PUT_LINE(v_dept.loc);
END;
/
3.2.2 自定义单行多列数据类型
自定义单行多列数据类型的语法规格如下:
TYPE record_name_type IS RECORD(
field1_name data_type [NOT NULL][DEFAULT|:=]default_value,
...
);
下面是自定义单行多列数据类型的使用例子:
DECLARE
TYPE emp_record_type IS RECORD(
name emp.ename%TYPE,
salary emp.sal%TYPE,
dno emp.deptno%TYPE
);
emp_record emp_record_type;
BEGIN
SELECT ename,sal,deptno INTO emp_record FROM emp WHERE empno=7788;
/*也可以这样使用
SELECT ename,sal INTO emp_record.name,emp_record.salary FROM emp WHERE empno=7788;
*/
DBMS_OUTPUT.PUT_LINE(emp_record.name);
END;
/
3.3 多行单列数据类型
多行单列数据类型或者可以称其为集合变量类型.集合类型包括索引表(PL/SQL表),嵌套表(Nested Table)和变长数组(VARRAY)3种类型.下面分别详细介绍三种集合类型的异同点.
3.3.1索引表(PL/SQL表)
索引表也称为PL/SQL表,用于处理PL/SQL数组的数据类型.但是索引表与高级语言的数组是有区别的:高级语言数组的元素个数是有限制的,并且下标不能为负值;而索引表的元素个数没有限制,并且下标可以为负值,甚至可以使用VARCHAR2类型.
PL/SQL中是没有现成的索引表数据类型的,要使用索引表,必须先进行数据类型定义,其定义语法为:
TYPE type_name IS TABLE OF element_type [NOT NULL] INDEX BY key_type; --type_name:自定义索引表数据类型的名称(IS TABLE ... INDEX表示索引表类型)
--element_type:用于指定索引表中每个元素的数据类型.如CHAR,NUMBER,VARCHAR2,emp.ename%TYPE等等.
--NOT NULL:表示不允许引用NULL元素
--key_type:用于指定索引表元素下标的数据类型,可以使用(BINARY_INTEGER,PLS_INTEGER或VARCHAR2).
Notice:索引表只能作为PL/SQL复合数据类型使用,而不能作为表列的数据类型使用.
Example:
DECLARE
TYPE ename_table_type IS TABLE OF emp.ename%TYPE INDEX BY BINARY_INTEGER;
ename_table ename_table_type; TYPE area_table_type IS TABLE OF NUMBER INDEX BY VARCHAR2(10);
area_table area_table_type;
BEGIN
SELECT ename INTO ename_table(-1) FROM emp WHERE empno=7788;
DBMS_OUTPUT.PUT_LINE('雇员号为7788的雇员名为'||ename_table(-1));
SELECT ename INTO ename_table(2) FROM emp WHERE empno=7369;
DBMS_OUTPUT.PUT_LINE('雇员号为7369的雇员名为'||ename_table(2)); area_table('北京'):=1;
area_table('上海'):=2;
area_table('广州'):=3;
DBMS_OUTPUT.PUT_LINE('第一个元素:'||area_table.first);
DBMS_OUTPUT.PUT_LINE('最后一个元素:'||area_table.last);
DBMS_OUTPUT.PUT_LINE('元素为"北京"的下一个元素:'||area_table.next('北京')); END;
/
Result:
3.3.2 嵌套表(Nested Table)
嵌套表类型与高级语言数据的区别:高级语言数组的元素下标从0或1开始,并且元素个数是有限制的,元素值是有顺序的;而嵌套表的元素下标从1开始,并且元素个数没有限制,元素值是无序的.
索引表类型与嵌套表类型的区别:索引表类型不能作为表列的数据类型使用,但嵌套表类型可以作为表列的数据类型使用.
嵌套表类型与索引表类型一样,没有现在的数据类型,要使用嵌套表类型必须首先自定义该类型,自定义嵌套表类型的语法规格如下:
TYPE type_name IS TABLE OF element_type; --type_name:用于指定嵌套表类型的类型名.
--element_type:用于指定嵌套表内的元素的数据类型.
Example:在PL/SQL块中使用嵌套表
DECLARE
TYPE ename_table_type IS TABLE OF emp.ename%TYPE;
ename_table ename_table_type;
BEGIN
--ename_table:=ename_table_type('','');
SELECT ename INTO ename_table(2) FROM emp WHERE empno=7788;
DBMS_OUTPUT.PUT_LINE('雇员名:'||ename_table(2));
END;
/
Example:在表列中使用嵌套表
在上面的例子中,会自动地创建表phone_table来保存phone字段的数据。
Example:在PL/SQL块中为嵌套表列插入数据
BEGIN
INSERT INTO employee VALUES(1,'SCOTT',800,phone_type('12345678','87654321'));
END;
/
Example:在PL/SQL块中检索嵌套表列的数据
DECLARE
phone_table phone_type;
BEGIN
SELECT phone INTO phone_table FROM employee WHERE id=1;
FOR i IN 1..phone_table.COUNT LOOP
DBMS_OUTPUT.PUT_LINE('电话号码:'||phone_table(i));
END LOOP;
END;
/
Example:在PL/SQL块中更新嵌套表列的数据
DECLARE
phone_table phone_type:=phone_type('00000000','11111111'); BEGIN
UPDATE employee SET phone=phone_table where id=1;
/*也可以这样
UPDATE employee SET phone=phone_type('00000000','11111111') where id=1;
*/
END;
/
3.3.3变长数组(VARRAY)
变长数组也是一种用于处理PL/SQL数组的数据类型,它也可以作为表列的数据类型使用.该数据类型与高级语言数组非常相似,其元素下标从1开始,并且元素的最大个数是有限制的.定义VARRAY的语法如下:
TYPE type_name IS VARRAY(size_limit) OF element_type [NOT NULL]; --type_name:用于指定VARRAY类型名
--size_limit:用于指定VARRAY元素的最大个数.
--element_type:用于指定元素的数据类型
Notice:当使用VARRAY元素时,必须使用其构造方法初始化VARRAY元素
Example:在PL/SQL块中使用VARRAY
DECLARE
TYPE ename_table_type IS VARRAY(20) OF emp.ename%TYPE;
ename_table ename_table_type;
BEGIN
ename_table:=ename_table_type('','');
SELECT ename INTO ename_table(2) FROM emp WHERE empno=7788;
DBMS_OUTPUT.PUT_LINE('雇员名:'||ename_table(2));
END;
/
Notice:关于变长数组在表列中的使用可以参考嵌套表,非常类似.唯一的区别是VARRAY不需要使用 NESTED TABLE子句
3.3.4三种集合类型的比较
三种集合类型的异同总结在下表中:
索引表 | 嵌套表 | 变长数组 | 高级语言数组 | |
元素下标 |
可以是负值,甚至使用VARCHAR2类型 |
从1开始 | 从1开始 | 从0或1开始 |
元素个数限制 | 无限制 | 无限制 | 有限制 | 有限制 |
是否需要初始化 | 不需要 | 需要 | 需要 | 需要 |
是否可用作表列类型 | 不可以 | 可以 | 可以 |
3.3.5集合方法
集合方法是Oracle所提供的用于操作集合变量的内置函数或过程,其中EXISTS()、COUNT()、LIMIT()、FIRST()、NEXT()、PRIOR()和LAST()是函数,而EXTEND()、TRIM()和DELETE()则是过程。集合方法的调用语法如下:
collection_name.method_name{(parameters)}
Notice:集合方法只能在PL/SQL语句中使用,而不能在SQL语句中调用。另外集合方法EXTEND和TRIM只适合于嵌套表和VARRAY,而不适用于索引表。
下表总结了各方法的使用:
方法名 | 用法描述 | 例子 |
EXISTS(下标值) | 参数的下标值,判断某个下标的元素时否存在,存在返回TRUE,否则返回FALSE | ename_table.EXISTS(1) |
COUNT() | 返回集合变量中的元素总个数,如果集合元素为NULL,则统计结果不包含该元素 | ename_table.COUNT |
LIMIT() | 返回集合变量可容元素的最大个数。因为嵌套表和索引表的元素个数没有限制,所以返回NULL | ename_table.LIMIT |
FIRST() | 返回集合变量第一个元素的下标 | ename_table.FIRST() |
LAST() | 返回集合变量最后一个元素的下标 | ename_table.LAST() |
PRIOR(下标值) | 返回参数中指定的下标值的前一个元素的下标 | ename_table.PRIOR(2) |
NEXT(下标值) | 返回参数中指定的下标值的下一个元素的下标 | ename_table.NEXT(1) |
EXTEND EXTEND(n) EXTEND(n,i) |
(只适用于嵌套表和VARRAY)该方法用于扩展集合变量的尺寸,并为它们增加元素。其中 EXTEND为集合变量增加一个NULL元素,EXTEND(n)为集合变量添加n个NULL元素,而 EXTEND(n,i)为集合变量增加n个元素(元素值与第i个元素相同) |
ename_table.EXTEND(10,1) |
TRIM TRIM(n) |
(只适合于嵌套表和VARRAY) TRIM从集合尾部删除一个元素,而TRIM(n)从集合尾部删除n个元素 |
ename_table.TRIM(2) |
DELETE DELETE(n) DELETE(m,n) |
(只适合于嵌套表和索引表)DELETE用于删除集合变量的所有元素;DELETE(n)用于删除集合 变量的第n个元素;而DELETE(m,n)用于删除集合变量第m到n之间的所有元素 |
ename_table.DELETE(2,5) |
3.4 多行多列数据类型——游标
在PL/SQL中,针对多行多列的数据类型,可以使用游标变量。
PL/SQL的游标指把从数据库中查询出来的数据以临时表的形式存放在内存中.游标可以对存储在内存中的数据进行操作,返回一条或一组记录,或者一条记录都不返回.
3.4.1游标的基本操作
游标包括两种游标:隐含游标和显式游标.隐含游标用于处理SELECT INTO和DML语句,而显式游标则专门用于处理SELECT语句返回的多行数据.
游标的基本操作有:声明游标、打开游标、提取游标和关闭游标。
下面的代码块展示了这四个基本操作:
DECLARE
CURSOR c_emp IS SELECT * FROM EMP; --声明游标
emp_record emp%ROWTYPE;
BEGIN
OPEN c_emp; --打开游标
LOOP
FETCH c_emp INTO emp_record; --提取游标
DBMS_OUTPUT.PUT_LINE('雇员名称:'||emp_record.ename);
EXIT WHEN c_emp%NOTFOUND;
END LOOP;
CLOSE c_emp; --关闭游标
END;
/
3.4.2游标属性
游标作为一个临时表,可以通过游标的属性来获取游标状态.游标有4个常用的属性:
- %ISOPEN:用于判断游标是否已经打开
- %FOUND:用于判断游标是否找到记录
- %NOTFOUND:与%FOUND相反.
- %ROWCOUNT:返回到当前为止已经提取到的实际行数.
3.4.3参数化游标
参数化游标是指带有参数的游标,在定义了参数游标之后,当使用不同的参数值多次打开游标时,可以生成不同的结果集.参数化游标的声明语法如下:
CURSOR cursor_name(parameter) IS SELECE ...
Example:参数化游标的使用
DECLARE
CURSOR emp_cursor(dno NUMBER) IS
SELECT ename FROM emp WHERE deptno=dno;
v_ename emp.ename%TYPE;
BEGIN
OPEN emp_cursor(10);
LOOP
FETCH emp_cursor INTO v_ename;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE(v_ename);
END LOOP;
CLOSE emp_cursor;
END;
/
3.4.4隐式游标
隐式游标就是指非PL/SQL程序中定义的,而且是在PL/SQL中使用UPDATE、DELETE或SELECT INTO语句时,Oracle系统自动分配的游标。隐式游标名称固定为SQL。隐式游标无须声明和打开,使用完后也不用关闭,所有这一切都由系统自动维护。
Example:SELECT INTO的隐式游标
DECLARE
v_emp emp%ROWTYPE;
BEGIN
SELECT * INTO v_emp FROM emp WHERE empno=7788;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('7788的雇员名称:'||v_emp.ename);
END IF;
END;
/
Example:UPDATE的隐式游标
BEGIN
UPDATE emp SET ename='SCOTT' WHERE empno=7788;
IF SQL%FOUND THEN
DBMS_OUTPUT.PUT_LINE('更新成功!');
END IF;
END;
/
3.4.5使用游标更新或删除数据
通过使用显式游标,不仅可以一行一行地处理SELECT语句的结果,而且也可以更新或删除当前游标行的数据。在使用游标更新或删除数据时有两点需要注意的地方:
- 声明游标是必须带有FOR UPDATE子句,如:
CURSOR cursor_name IS SELECT ... FOR UPDATE;
- 在提取了游标数据之后,为了更新或删除当前游标行数据,必须在UPDATE或DELETE语句中引用WHERE CURRENT OF子句。如:
UPDATE table_name SET column=... WHERE CURRENT OF cursor_name;
DELETE table_name WHERE CURRENT OF cursor_name;
Example:使用游标更新数据
DECLARE
CURSOR emp_cursor IS SELECT ename,sal FROM emp FOR UPDATE;
v_ename emp.ename%TYPE;
v_sal emp.sal%TYPE;
BEGIN
OPEN emp_cursor;
LOOP
FETCH emp_cursor INTO v_ename,v_sal;
EXIT WHEN emp_cursor%NOTFOUND;
IF v_sal<2000 THEN
UPDATE emp SET sal=sal+100 WHERE CURRENT OF emp_cursor;
END IF;
END LOOP;
CLOSE emp_cursor;
END;
/
3.4.6 游标FOR循环
当使用游标FOR循环时,Oracle会隐含地打开游标、提取游标数据并关闭游标。
Example:使用游标FOR循环
DECLARE
CURSOR emp_cursor IS SELECT * FROM emp;
v_emp emp%ROWTYPE;
BEGIN
FOR v_emp IN emp_cursor LOOP
DBMS_OUTPUT.PUT_LINE('第'||emp_cursor%ROWCOUNT||'个雇员'||v_emp.ename);
END LOOP;
END;
/
Example: 在游标FOR循环中直接使用子查询
DECLARE
v_emp emp%ROWTYPE;
BEGIN
FOR v_emp IN (SELECT * FROM EMP) LOOP
DBMS_OUTPUT.PUT_LINE('编号'||v_emp.empno||'的雇员名称:'||v_emp.ename);
END LOOP;
END;
/
3.4.7 游标变量
上面提到的显式游标和隐式游标都与固定的查询语句相关联,所以称之为静态游标。游标变量与静态游标不同,它是一种动态游标,在运行期间可以与不同的查询语句相关联。
要声明游标变量,首先得创建一个游标数据类型,创建游标数据类型的语法如下:
TYPE cursor_data_type_name IS REF CURSOR [RETURN return_type];
Example:操作游标变量
DECLARE
TYPE emp_cursor_type IS REF CURSOR RETURN emp%ROWTYPE;
emp_cursor emp_cursor_type;
emp_record emp%ROWTYPE;
BEGIN
IF NOT emp_cursor%ISOPEN THEN
OPEN emp_cursor FOR SELECT * FROM emp WHERE deptno=10;
END IF;
LOOP
FETCH emp_cursor INTO emp_record;
EXIT WHEN emp_cursor%NOTFOUND;
DBMS_OUTPUT.PUT_LINE('雇员名:'||emp_record.ename);
END LOOP;
END;
/
4 PL/SQL的控制结构
4.1 IF语句
IF语句的语法:
IF condition1 THEN
statement1;
ELSIF condition2 THEN
statement2;
ELSE
statement3;
END IF;
4.2 CASE语句
CASE语句语法:
CASE variable_name
WHEN case1 THEN statement1;
WHEN case2 THEN statement2;
...
WHEN caseN-1 THEN statementN-1;
[ELSE statementN]
END CASE;
Example:CASE语句的使用
DECLARE
grade CHAR :='B';
appraisal VARCHAR2(20);
BEGIN
appraisal :=
CASE grade
WHEN 'A' THEN '优'
WHEN 'B' THEN '良'
ELSE '不及格'
END;
DBMS_OUTPUT.PUT_LINE('Grade '||grade|| ' is '||appraisal); /*下面效果一样
grade:='A';
CASE grade
WHEN 'A' THEN appraisal :='优';
WHEN 'B' THEN appraisal :='良';
ELSE appraisal :='不及格';
END CASE;
DBMS_OUTPUT.PUT_LINE('Grade '||grade|| ' is '||appraisal); */
END;
/
4.3基本循环
基本循环的语法:
LOOP
statements
EXIT [WHEN condition]
END LOOP;
4.4WHILE循环
WHILE循环语法:
WHILE condition LOOP
statements;
END LOOP;
4.5 FOR循环
FOR循环语法
FOR loop_variable IN [REVERSE] lower_bound..upper_bound LOOP
statements;
END LOOP;
Example:FOR循环的使用
DECLARE
i INTEGER;
BEGIN
FOR i IN REVERSE 1..3 LOOP
DBMS_OUTPUT.PUT_LINE(i);
END LOOP;
END;
/
5 异常处理
Oracle系统中的异常分为系统预定义异常和用户自定义异常。异常处理的一般语法如下:
EXCEPTION
WHEN exception1 THEN
statements1;
WHEN exception2 THEN
statements2;
WHEN OTHERS THEN
statements3;
5.1系统预定义异常
错误信息 | 异常错误名称 | 说明 |
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 | Stroage-error | 内存不够引发的内部错误 |
ORA-6501 | Program-error | 内部错误 |
ORA-6502 | Value-error | 转换或截断错误 |
ORA-6504 | Rowtype-mismatch | 主变量和游标的类型不兼容 |
ORA-6511 | CURSOR-ALERADY-OPEN | 试图打开一个已经打开的游标 |
ORA-6530 | ACCESS_INTO_NULL | 试图为null对象的属性赋值(如一个对象没初始化时,向其内部属性赋值) |
Example:NO_DATA_FOUND异常的处理
DECLARE
v_sal emp.sal%TYPE;
BEGIN
SELECT SAL INTO v_sal FROM emp WHERE ename='MARY';
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('不存在该雇员!');
END;
/
5.2用户自定义异常
用户自定义异常的语法:
exception_name EXCEPTION;
PRAGMA EXCEPTION_INTO(exception_name,exception_no); --PRAGMA关键字用于把某个异常名和异常号关联起来
在声明了自定义异常后,便可以使用RAISE语句显式触发异常了。
Example:触发用户自定义异常
DECLARE
e_no_employee EXCEPTION;
PRAGMA EXCEPTION_INIT(e_no_employee,-2291);
BEGIN
UPDATE emp SET deptno=10 WHERE empno=1111;
IF SQL%NOTFOUND THEN
RAISE e_no_employee;
END IF;
EXCEPTION
WHEN e_no_employee THEN
DBMS_OUTPUT.PUT_LINE('该雇员不存在!');
END;
/
5.3异常函数
- SQLCODE()和SQLERRM()
SQLCODE()用于返回Oracle错误号,而SQLERRM()用于返回该错误号对应的错误消息。 - RAISE_APPLICATION_ERROR
该过程用于在 PL/SQL应用程序中自定义错误消息。该过程只能在(过程、函数、包、触发器)中使用。
Example:SQLCODE()和SQLERRM()的使用
DECLARE
v_ename emp.ename%TYPE;
BEGIN
SELECT ename INTO v_ename FROM emp WHERE deptno=10;
DBMS_OUTPUT.PUT_LINE('雇员名:'||v_ename);
EXCEPTION
WHEN NO_DATA_FOUND THEN
DBMS_OUTPUT.PUT_LINE('雇员不存在!');
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE('错误号:'||SQLCODE);
DBMS_OUTPUT.PUT_LINE(SQLERRM);
END;
/
Example:RAISE_APPLICATION_ERROR的使用(略)
RAISE_APPLICATION_ERROR('-20001','该雇员无补助');
PL/SQL之基础篇的更多相关文章
- oracle PL/SQL语法基础
目录 数据类型 定义变量 PL/SQL控制结构 参考资料 Oracle10g数据类型总结 PL/SQL之基础篇 数据类型 学习总结 字符类型 char.nchar.varchar.nvarchar:有 ...
- PL/SQL之高级篇
原文地址:http://www.cnblogs.com/sin90lzc/archive/2012/08/30/2661117.html 参考文献:<Oracle完全学习手册> 1.概述 ...
- Oracle数据库编程:PL/SQL编程基础
2.PL/SQL编程基础: PL/SQL块: declare 定义部分 begin 执行部分 exception 异 ...
- Oracle Pl/SQL编程基础
Pl/SQL简介 提高应用程序的运行性能, 提供模块化的程序设计, 自定义标示符, 具有过程语言控制结构, 良好的兼容性, 处理运行错误. Pl/SQL语言基础 sql是关系数据库的基本操作语言. s ...
- 【PL/SQL编程基础】
[PL/SQL编程基础]语法: declare 声明部分,例如定义变量.常量.游标 begin 程序编写,SQL语句 exception 处理异常 end: / 正斜杠表示执行程序快范例 -- Cre ...
- PL/SQL语言基础
PL/SQL语言基础 进行PL/SQL编程前,要打开输出set serveroutput on 1.创建一个匿名PL/SQL块,将下列字符输出到屏幕:"My PL/SQL Block Wor ...
- oracle(sql)基础篇系列(五)——PLSQL、游标、存储过程、触发器
PL/SQL PL/SQL 简介 每一种数据库都有这样的一种语言,PL/SQL 是在Oracle里面的一种编程语言,在Oracle内部使用的编程语言.我们知道SQL语言是没有分支和循环的,而PL语 ...
- oracle(sql)基础篇系列(五)——PLSQL、游标、存储过程、触发器
PL/SQL PL/SQL 简介 每一种数据库都有这样的一种语言,PL/SQL 是在Oracle里面的一种编程语言,在Oracle内部使用的编程语言.我们知道SQL语言是没有分支和循环的,而PL语言是 ...
- PL/SQL编程基础(三):数据类型划分
数据类型划分 在Oracle之中所提供的数据类型,一共分为四类: 标量类型(SCALAR,或称基本数据类型) 用于保存单个值,例如:字符串.数字.日期.布尔: 标量类型只是作为单一类型的数据存在,有的 ...
随机推荐
- 名字竞技场 V3.0
更新内容 1.加入新boss,更高的难度. 2.支持组队模式勒! 3.针对大家反应的人物属性算法进行了修改,现在人物属性更多的取决于名字而不是随机数 4.用户界面优化 INF.代码拿走赞留下,不然你赢 ...
- ssm 数据库连接池配置
1.工程引入druid-1.1.2.jar包2.修改spring-common.xml文件 <!-- 1. 数据源 : DruidDataSource--> <bean id=&qu ...
- DOMContentLoaded 与onload区别以及使用
一.何时触发这两个事件? 1.当 onload 事件触发时,页面上所有的DOM,样式表,脚本,图片,flash都已经加载完成了. 2.当 DOMContentLoaded 事件触发时,仅当DOM加载完 ...
- 洛谷—— P1077 摆花
https://www.luogu.org/problem/show?pid=1077 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共m盆.通过调查顾客的喜好,小明列出了顾客 ...
- N天学习一个Linux命令之dmesg
用途 显示系统自检信息和设备信息 用法 dmesg [-c] [-r] [-n level] [-s bufsize] 常用选项 选项 含义 说明 -c 输出ring buffer内容并且清空ring ...
- mongodb之集群模式
前言 数据量大了或者并发量上来了,单机肯定是抗不住的,这个时候要开始考虑使用集群了.mongodb目前为止支持三种集群模式:主从集群,副本集集群,分片集群. 主从集群 特性 1. 一主多从2. 主负责 ...
- Intellij Idea 13:重置设置
最近在将Windows下的Idea的设置导入到Mac下的时候,一时手贱,点了全部结果发现悲剧了,所有的快捷键都变成和Windows的一样了.于是我就在CMD+C,V和Ctrl+C,V中不断的进行头脑锻 ...
- ural 1468
写了好久,不知道为什么不过,也不清楚到底卡在哪里... 只好看别人的代码,感觉除了HASH不一样外,倒没什么特别之处.同时参考那论文写的.. http://blog.csdn.net/jyysc201 ...
- Retrofit网络框架入门使用
1.简单介绍 retrofit事实上就是对okhttp做了进一步一层封装优化. 我们仅仅须要通过简单的配置就能使用retrofit来进行网络请求了. Retrofit能够直接返回Bean对象,比如假设 ...
- 关于创建Android Library所须要知道的一切
关于创建Android Library所须要知道的一切 Android 库(Library)在结构上与 Android 应用模块同样.应用模块所能够包括的东西.在库中都同意存在,包括代码文件.资源文件 ...