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有四种类型:
1、CLOB:字符大对象,存储在数据库内部;
2、NCLOB:多字节字符大对象,存储在数据库内部;
3、BLOB:二进制大对象,存储在数据库内部;
4、BFILE:二进制文件,存储在数据库外部;
创建Trigger:Trigger的定义语句里面涉及到如下关键因素:
时机:Before或者After或Instead of
事件:Insert或Update或Delete
对象:表名(或视图名)
类型: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: 权限