> a:=a+1注意:不可以同外层跳到里层
不可以从一个IF子句跳到另一个IF子句 不可以从异常处理块跳到当前块
6、 select into 为变量赋值
select name into v_name where …
六、游标
游标的本质是SQL语句的一个工作区域,用于处理多行记录集的查询。 分类:Implicit cursors:由DML和PL/SQL的SELECT隐式的定义,不可以使用open,fetch
和close去控制这个sql 游标。每一次只处理一行。但是可以使用游标的属性
Explicit cursors:由程序员定义, 显式游标用于返回多于一行的查询
以下讨论的都是显式游标 执行的四个步骤:
1、声明:定义游标的名字和结构,select 中可以使用order by 2、 打开游标:执行查询同时绑定所有涉及到的变量
执行的内容:
为select 分配内存并分析select语句 绑定输入的变量
配置指针在活动集的第一行
注意:如果 查询不返回结果,不会引发PL/SQL的异常,你可以在执行fetch后
测试返回的结果
如果游标内的声明包括update。一样会执行行锁定
3、 Fetch:把当前行的值赋给变量,每个fetch都会把游标指针向下移动一行。            如果到了最后一行就会自动退出for loop
4、
关闭:释放活动的集,可以再次使用open
游标的几个属性:
SQL%ROWCOUNT 受最近执行的SQL语句影响的行的数目。(一个整数值)
SQL%FOUND Boolean属性,如果最近的SQL语句影响了一行或多行,其值为  TRUE。
SQL%NOTFOUND Boolean属性,如果最近的SQL语句没有影响任何行,其值为  TRUE。
SQL%ISOPEN 总是为FALSE,原因是PL/SQL总是它们结束执行后立即关闭内隐游标。
例子
EG1:常规用法
CURSOR c1 IS
SELECT empno, ename     FROM  emp;
emp_record c1%ROWTYPE; BEGIN
OPEN c1; . . .
FETCH c1 INTO emp_record;
EG2:使用for循环实现游标
DECLARE
CURSOR c1 IS
SELECT empno, ename
FROM   emp;
emp_record c1%ROWTYPE; BEGIN
FOR emp_record IN c1 LOOP
-- implicit open and implicit fetch occur     IF emp_record.empno = 7839 THEN       ...
END LOOP; -- implicit close occurs END;
游标FOR循环立时不需要FETCH语句的。游标打开,在循环中每次重复提取一行,所有的行都处理后,游标会自动关闭。
EG3:不定义游标的方式
BEGIN
FOR emp_record IN ( SELECT empno, ename                        FROM   emp) LOOP
-- implicit open and implicit fetch occur     IF emp_record.empno = 7839 THEN       ...
END LOOP; -- implicit close occurs END;
EG4:带变量的游标------ 你必须指定指定参数的数据类型,但不用指定大小
DECLARE
CURSOR c1
(v_deptno NUMBER, v_job VARCHAR2) IS     SELECT empno, ename     FROM emp
WHERE deptno = v_deptno       AND  job = v_job; BEGIN
OPEN c1(10, 'CLERK'); ...
EG5:FOR UPDATE----当加上for update则把整个表或字段锁住了。
SELECT ... FROM  ...
FOR UPDATE [OF column_reference][NOWAIT]
DECLARE
CURSOR c1 IS
SELECT empno, ename      FROM   emp
FOR UPDATE NOWAIT;
NOWAIT:返回一个oracle的错误信息如果此行给其他的会话锁住了。
EG6:WHERE CURRENT OF
用于在游标中删除和更新当前行 必须使用 FORUPDATE去锁住行
使用WHERE CURRENT OF去指向当前的行 DECLARE
CURSOR c1 IS     SELECT ...
FOR UPDATE NOWAIT; BEGIN   ...
FOR emp_record IN c1 LOOP     UPDATE ...
WHERE CURRENT OF c1;     ...   END LOOP;   COMMIT; END;
七、处理异常
Predefined Exception
BEGIN  SELECT ... COMMIT; EXCEPTION
WHEN NO_DATA_FOUND THEN
statement1;
statement2;                   WHEN TOO_MANY_ROWS THEN     statement1;   WHEN OTHERS THEN     statement1;      statement2;      statement3; END;  …….
Non-Predefined Exception
DECLARE
e_products_invalid EXCEPTION;   PRAGMA EXCEPTION_INIT (
e_products_invalid, -2292);   v_message VARCHAR2(50); BEGIN . . . EXCEPTION
WHEN e_products_invalid THEN     :g_message := 'Product code   specified is not valid.'; . . . END;
User-Defined Exception
DECLARE
e_amount_remaining EXCEPTION; . . . BEGIN . . .
RAISE e_amount_remaining; . . . EXCEPTION
WHEN e_amount_remaining  THEN
:g_message := 'There is still an amount               in stock.'; . . . END;
RAISE_APPLICATION_ERROR
DECLARE     …….
Invalidpart EXCEPTION; BEGIN
    
…….
IF SQL%NOTFOUND THEN    RAISE invalidpart;    END IF; EXCEPTION
WHEN invalidpart THEN
Raise_application_error(-20003,’Invalid Part id #’||  partnum);    WHEN OTHERS THEN
Raise_application_error(-20000,errNum||errMsg);    END
使用EXCEPTION关键字在一个PL/SQL块的声明部分声明用户自定义异常 使用PL/SQL命令RAISE检测用户自定义异常
PL/SQL可使用Raise_application_error过程返回一个用户自定义错误数和消息给调用环境。所有的用户自定义错误消息必须在-20000到-20999之间
PL/SQL程序可以使用WHEN OTHERS 异常处理来处理没有特定处理的所有异常 PL/SQL程序可以使用特殊的SQLCODE和SQLERRM函数返回最新的oracle错误号码和消息
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;
数据库联接
定义:CREATE DATABASE LINK link_name
CONNECT TO username IDENTIFIED BY password
USING sqlnet_string;
使用:表名@link_name
替代名
CREATE SYNONYM synonym_name FOR reference; Eg:CREATE SYNONYM backup FOR backup@esal