OraclePL/SQL(三)

2014-11-24 12:48:45 · 作者: · 浏览: 4
mployees.last_name%TYPE

INDEX BY BINARY_INTEGER;

ename_table ename_table_type;

隐式游标的几个有用属性:

SQL%ROWCOUNT 受最近的SQL语句影响的行数

SQL%FOUND 最近的SQL语句是否影响了一行以上的数据

SQL%NOTFOUND 最近的SQL语句是否未影响任何数据

SQL%ISOPEN 对于隐式游标而言永远为FALSE

显式游标的相关函数可以做到:

1、一行一行的处理返回的数据。

2、保持当前处理行的一个跟踪,像一个指针一样指示当前的处理的记录。

3、允许程序员在PLSQL块中人为的控制游标的开启、关闭、上下移动;

游标推荐写法

DECLARE

CURSOR emp_cursor IS

SELECT last_name, department_id

FROM employees;

BEGIN

FOR emp_record IN emp_cursor LOOP

-- implicit open and implicit fetch occur

IF emp_record.department_id = 80 THEN

...

END LOOP; -- implicit close occurs

END;

异常处理

BEGIN

. . .

EXCEPTION

WHEN NO_DATA_FOUND THEN

statement1;

WHEN TOO_MANY_ROWS THEN

statement1;

WHEN OTHERS THEN

statement1;

statement2;

END;

OTHERS

DECLARE

v_error_code NUMBER;

v_error_message VARCHAR2(255);

BEGIN

...

EXCEPTION

...

WHEN OTHERS THEN

ROLLBACK;

v_error_code := SQLCODE ;

v_error_message := SQLERRM ;

INSERT INTO errors

VALUES(v_error_code, v_error_message);

END;

想要在SQL语句中可以使用用户自定义的函数,那么这样的用户定义函数有哪些限制?

答: 有如下限制:

必须是个函数(不能是过程-Procedure)

只能用IN 模式的参数(不能有OUT, IN OUT 模式的参数)

只能接收SQL数据类型的参数,不能接收PLSQL 中特有的参数(比如记录、PLSQL内

存表)

函数返回的数据类型也必须是有效的数据类型,而不能是PLSQL特有的数据类型

在SQL中使用的函数,其函数体内部不能有DML语句。

在UPDATE/DELETE语句中调用的函数,其函数体内部不能有针对同一张表的查询语句

在SQL中调用的函数,其函数体内部不能有事务结束语句(比如Commit,Rollback)

定义者权限:函数执行时,对表的访问默认使用定义者权限。

那么什么情况会使用调用者权限呢?这需要在写函数的时候有特殊语句标识:AUTHID CURRENT_USER

Package好处:

1、模块化:一般把有相关性的函数和过程放到一个Package中;

2、易设计:可以把包说明和包体分别编写和编译,先编写和编译包说明部分,在编写和说明包体部分;这有利

于分工合作;

3、信息隐藏:包体中函数可以部分出现在包说明中,只有出现在包说明中的函数和过程才是该Package的公有

函数和过程,可以被其他包中的函数调用,否则对其他包中的函数是不可见的,未在包说明部分出现的函数

和过程相当于私有的。

4、加载性能提高:当Package中有一个函数或过程被调用时,整个Packege就被加载到内存中,这样当该

Package中其他函数被调用时,就直接从内存读取了,可以减少磁盘IO,从而提高性能。这个特性也提醒

我们不要去搞巨无霸的Package,把你用到的任何函数都写到一个Package中,这会导致严重的内存浪费。

5、重载:一个package中可以定义同名、不同参数的函数或过程。

存储过程

FOR UPDATE NOWAIT语句:有的时候我们打开一个游标是为了更新或者删除一些记录,这种情况下我们希望

在打开游标的时候即锁定相关记录,应该使用for update nowait语句,倘若锁定失败我们就停止不再继续,以免出现长时间等待资源的死锁情况。

DECLARE

CURSOR sal_cursor IS

SELECT e.department_id, employee_id, last_name, salary

FROM employees e, departments d

WHERE d.department_id = e.department_id

and d.department_id = 60

FOR UPDATE OF salary NOWAIT;

BEGIN

FOR emp_record IN sal_cursor

LOOP

IF emp_record.salary < 5000 THEN

UPDATE employees

SET salary = emp_record.salary * 1.10

WHERE CURRENT OF sal_cursor;

END IF;

END LOOP;

END;

动态SQL:不是在Designer Time写的SQL,而是可以在运行时临时拼接起来的SQL语句;

动态SQL可以使用Oracle内置包DBMS_SQL来执行,也可以使用EXECUTE IMMEDIATE语句来执行:

v_filehandle := UTL_FILE.FOPEN (p_filedir, p_filename,'w');

UTL_FILE.PUTF (v_filehandle,'SALARY REPORT: GENERATED ON

%s\n', SYSDATE);

UTL_FILE.NEW_LINE(v_filehandle);

Oracle数据库里面的LOB有四种类型:

1CLOB:字符大对象,存储在数据库内部;

2NCLOB:多字节字符大对象,存储在数据库内部;

3BLOB:二进制大对象,存储在数据库内部;

4BFILE:二进制文件,存储在数据库外部;

创建TriggerTrigger的定义语句里面涉及到如下关键因素:

时机:Before或者AfterInstead of

事件:InsertUpdateDelete

对象:表名(或视图名)

类型:Row或者Statement级;

条件:满足特定Where条件才执行;

内容:通常是一段PLSQL块代码;

重点注意:

Instead of : Trigger的内容替换事件本身的动作

Row级:SQL语句影响到的每一行都会引发Trigger

Statement级:一句SQL语句引发一次,不管它影响多少行(甚至0行)

PLSQL

1. Oracle 同义词

相当于alias(别名),比如把user1.table1在user2中建一个同义词table1

create synonym table1 for user1.table1;

这样当你在user2中查select * from table1时就相当于查select * from user1.table1;

优点自己总结吧。

2. Oracle 受权 ORA-00990: 权限