Procedural Language SQL
1.范例:最简单的语句块
set serveroutput on; //可以在服务器端输出结果
begin
dbms_output.put_line(“hello world!”); //相当于system.out.println 不能输出boolean值
end;
/
2.范例:简单的PL/SQL语句块
declare //声明变量: 变量名 变量类型
v_name varchar2(20);
begin
v_name := ‘myname’;
dbms_output.put_line(v_name);
end;
3.范例:语句块的组成
declare
v_num number := 0;
begin
v_num = 2/v_num;
dbms_output.put_line(v_num);
exception
when others then
dbms_output.put_line(‘error’);
end;
4.变量声明的规则
变量名不能够使用保留字,必须字母开头,最多30个字符,不能与数据库表或列同名,每一行只能声明一个变量
5.常用的变量类型
binary——integer:整数,主要用来计数而不是用来表示字段类型
number:数字类型
char:定长字符串
varchar2:变长字符串
date:日期
long:长字符串,最长2GB
boolean:布尔类型 可取值true false null
使用%type属性:可以保证相关变量或字段的类型发生变化时用%type声明的变量类型同步更新
v_empno emp.empno%type; //用表中某个字段类型来定义变量
v_empno2 v_empno%type; //或 用某个变量的类型来声明变量
两种复合类型:
table 变量类型:相当于数组
//定义一种新的变量类型:类型名约定俗成 数组下标的类型(可为负)
type type_table_emp_empno is table of emp.empno%type index by binary_integer
v_empnos type_table_emp_empno;//再用类型声明变量
v_empnos(0) := 0;//对数组元素赋值
record变量类型:相当于类
type type_record_dept is record{
deptno dept.deptno%type,
dname dept.dname%type,
loc dept.loc%type
};
v_temp type_record_dept;
v_temp.dname := ‘deptname’;
在record中使用%rowtype声明相应字段(可以同步更新)
v_temp dept%rowtype;
6.在PL/SQL中:DML语句
①-- 可以注释掉一行
②select语句必须返回有且只有一条结果eg:
select ename,sal into v_ename,v_sal from emp where empno =7369; //into指向保存返回值的变量
③insert delete update直接用(区别在于使用变量而不是字段)commit;提交
④sql%rowcount //sql表示刚刚执行的sql语句,其属性rowcount表示影响多少条记录
select语句为1条记录被影响:表示最后产生一个值
⑤count(*)
7.在PL/SQL中:DDL语句 //单引号内部用两个单引号表示一个单引号
excute immediate ‘create table T (name varchar2(20) default ‘’aaa’’)’;
8.在PL/SQL中的分支、循环
①分支 | ②循环:相当于do-while |
if(条件1) then 语句; elsif(条件2)then //注意elsif 语句; else //注意else后没有then 语句; end if; //注意end if后边有分号 | declare i binary_integer :=1 ; begin loop 语句; i := i + 1 ; exit when(条件); end loop; end; |
②循环:相当于for | ②循环:相当于while |
for k in 1...10 loop 语句 end loop; for k in reverse 1...10 loop 语句 end loop; | declare i binary_integer :=1 ; begin while 条件 loop 语句; i := i + 1 ; end loop; end; |
9.错误处理:too_many_rows太多记录了 no_data_found没数据 others其他
exception
when 异常名字 then
异常处理语句
10.创建记录错误信息的表
create table errorlog(
id number primary key,
errcode number,
errmsg varchar2(1024),
errdate date
);
create sequence seq_errorlog_id start with 1 increment by 1;
在PL/SQL语句块中:
declare
v_errcode errorlog.errcode%type;
v_errmsg errorlog.errmsg%type;
begin
语句;
commit;
exception
when others then
rollback;
v_errlog := SQLCODE;
v_errmsg :=SQLERRM;
insert into errorlog values(seq_errorlog_id.nextval,v_errlog,v_errmsg,sysdate);
commit;
end
11.游标的遍历:取出每条记录并处理
declare cursor c is select * from emp; v_emp c%rowtype; begin open c; loop fetch c into v_emp; exit when (c%notfound); 语句用v_emp.ename等等取出某字段值; end loop; close c; end; | declare cursor c is select * from emp; begin //for自动声明v_emp同时自动open/fetch/close for v_emp in c loop 语句用v_emp.ename等等取出某字段值; end loop; end; |
12.带参数的游标:
declare
cursor c(v_deptno emp.deptno%type , v_job emp.job%type) is
select ename ,sal from emp where deptno=v_deptno and job=v_job;
begin
for v_temp in c(30,’CLERK’) loop
语句;
end loop; end;
13.可更新的游标 在声明 cursor的最后 加上for update;
update/delete.... where current of c;
14.存储过程:相当于替换declare 其他不变
①创建存储过程
create or replace procedure p is
.... ...
②调用存储过程
exec p; 或 begin p; end;
③带参数的存储过程
create or replace procedure p
(v_a in number,v_b in number ,v_ret out number,v_temp in out number)
is //传入参数 传出参数(返回值) 既传入又传出
.... ...
④调用带参数的存储过程:declare与形参对应的实参变量 在begin-end中调用p(实参列表)
⑤当存储过程内部发生错误时:创建的过程带有编译错误 但不具体指出哪里错了
使用show error显示具体错误信息
15. 触发器:
create or replace trigger trig
after insert or delete or update on emp for each row //另一种为before
begin
if inserting then 语句1;
elsif updating then 语句2;
elsif deleting then 语句3;
end if;
end
16. 函数
create or replace function sal_tax //函数名
(v_sal number) //函数参数
return number //函数返回值
is begin-end语句块
17.实现update dept set depno=90 where deptno =10 ; //违反完整约束条件
创建触发器 //很少使用:先触发器,再检查约束条件
create or replace trigger trig
afer update on dept for each row
begin //:NEW代表update的新状态 :OLD表示update的旧状态
update emp set deptno =:NEW.deptno where deptno =:OLD.deptno;
end
18.树状结构的存储与展示
create table article(
id number primary key,
cont varchar2(4000),
pid number, //回复的父节点id
isleaf number(1), //0代表非叶子节点 1代表叶子节点(没有其他回复了)
alevel number);
insert into article values (1,’楼主1楼帖子’,0,0,0)
insert into article values (2,’回复1楼帖子’,1,0,1)
insert into article values (3,’回复2楼帖子’,2,1,2)
insert into article values (4,’回复2楼帖子’,2,0,2)
insert into article values (5,’回复4楼帖子’,4,1,3)
insert into article values (6,’回复1楼帖子’,1,0,1)
insert into article values (7,’回复6楼帖子’,6,1,2)
insert into article values (8,’回复6楼帖子’,6,1,2)
insert into article values (9,’回复2楼帖子’,2,0,2)
insert into article values (10, 回复9楼帖子’,9,1,3)
对应的展示树状结构的存储过程:
create or replace procedure p (v_pid article.pid%type) is
cursor c is select * from article where pid=v_pid;
begin
for v_article in c loop
dbms_output.put_line(v_article.cont);
if(v_article.isleaf = 0) then
p(v_article.id);
end if;
end loop;
end;
19.PL/SQL缺点:数据库平台移植性差 只针对oracle