1、PL/SQL结合了过程语言和sql查询语言的扩展语言,就是为sql增加了编程语言的特点,通过逻辑判断、循环等操作实现复杂功能或计算。
[declare] --声明部分:声明用到的变量、类型、游标,以及局部的存储过程和函数 begin --执行部分:过程sql语句 [exception] --执行异常部分 end; 执行部分不能省略
pl/sql块分类:无名块、命名块、子程序、触发器、程序包
pl/sql符号:赋值 := 连接 || 单行注释 -- 多行注释 /**/ 范围操作 ..
1.1pl/sql变量声明
v_ename VARCHAR2(20); --声明变量的类型和长度
v_ename VARCHAR2(20) := 'tom'; --声明并赋值
程序变量 | v_name |
程序常量 | c_name |
游标变量 | cursor_name |
异常标志 | e_name |
表类型 | name_table_type |
表 | name_table |
记录类型 | name_record |
绑定变量 | g_name |
常用变量类型:char、varchar、binary_integer、number(p,s)、long、date、boolean
常用引用类型:%type、%rowtype
2.1流程控制
if <表达式> then --执行部分 end if; if <表达式> then --执行部分 elsif <表达式> then --执行部分 end if; case when <表达式1> then -- when <表达式2> then -- [else] end; case <表达式> when <表达式结果1> then -- when <表达式结果2> then -- [else] end;
--循环 loop --执行的语句 exit when <条件语句> --满足条件退出循环 end loop; for 循环计数器 in 【reverse】 下限 ... 上限 loop -- end loop; --例子: 1. for in loop形式 DECLARE CURSOR c_sal IS SELECT employee_id, first_name || last_name ename, salary FROM employees ; BEGIN --隐含打开游标 FOR v_sal IN c_sal LOOP --隐含执行一个FETCH语句 DBMS_OUTPUT.PUT_LINE(to_char(v_sal.employee_id)||'---'|| v_sal.ename||'---'||to_char(v_sal.salary)) ; --隐含监测c_sal%NOTFOUND END LOOP; --隐含关闭游标 END; 2.普通的游标循环 declare --定义游标并且赋值(is 不能和cursor分开使用) cursor stus_cur is select * from students; --定义rowtype cur_stu students%rowtype; /*开始执行*/ begin --开启游标 open stus_cur; --loop循环 loop --循环条件 exit when stus_cur%notfound; --游标值赋值到rowtype fetch stus_cur into cur_stu; --输出 dbms_output.put_line(cur_stu.name); --结束循环 end loop; --关闭游标 close stus_cur; /*结束执行*/ end; 3.高效的游标循环 declare cursor myemp_cur is select * from myemp; type myemp_tab is table of myemp%rowtype; myemp_rd myemp_tab; begin open myemp_cur; loop fetch myemp_cur bulk collect into myemp_rd limit 20; for i in 1..myemp_rd.count loop dbms_output.put_line('姓名:'||myemp_rd(i).ename); end loop; exit when myemp_cur%notfound; end loop; end;
--goto、null的使用 decllare v_counter number :=1; begin loop dbms_output.put_line(v_counter); v_conuter := v_counter +1; if v_conuter >10 then goto labeloffloop;--跳转到标签为lableoffloop的行 else null;--为了使语法变得有意义 end if; end loop; <<labeloffloop>> dbms_output.put_line(v_counter); end;
3、异常处理,常用的异常处理方法
常见的oracle预定义异常
DUP_VAL_ON_INDEX:重复存储唯一索引的数据库列出现
INVALID_NUMBER:将字符串转为数字时出现
NO_DATA_FOUND:表中不存在请求行时出现
TOO_MANY_ROWS:在执行select into 语句后返回多行时出现
VALUE_ERROR:变量的列值超出变量的大小
ZERO_DIVIDE:以零作为除数时出现
OTHERS:保证处理不漏过任何异常 ,可以使用函数sqlcode和sqlerrm返回错误代码和错误文本信息。
自定义异常使用
declare v_name emp.name%type; e_name_null exception; begin if v_name is null then raise e_name_null; end if; exception when e_name_null then dbms_output.line ('名字不能为空'); end; --注:raise_application_error存储过程,可以重新定义异常错误消息 --raise_application_error(error_number,error_message);