1.plsql: //数据库中使用的编程语言
PL/SQL(Procedure Language/SQL)是 Oracle 对 sql 语言的过程化扩展,
指在 SQL 命令语言中增加了过程处理语句(如分支、循环等),使 SQL 语言具有过程处理能力。
语法格式:
[declare
--声明变量
]
begin
--代码逻辑
[exception
--异常处理
]
end;
2.变量:
变量的声明:
变量名 类型(长度);
也可采用下面两种方式定义变量属性
1)引用型 //引用某表某列的字段类型
变量名 表名.列名%type
v_usenum T_ACCOUNT.USENUM%TYPE; //将v_usenum 的变量属性定义为t_account表中usenum的类型
2)记录型 //表示某个表所有行的类型
变量名 表名%rowtype
v_account T_ACCOUNT%ROWTYPE; //将v_account 的变量类型定义为记录型,表示的是t_account表字段类型
变量赋值:
1)变量名:=值;
2)从数据库表中得到数据并赋值给变量: //查询结果只能是一行记录,且得到的字段个数要和变量个数相同,一一对应
select 字段1,字段2,... into 变量名1,变量名2,... from t_account where id=1;
3)记录型变量的赋值取值
记录型变量的赋值: //同上也只能返回一行记录
select * into v_account from t_account
记录型变量的取值
v_account.usenum //通过'.'加字段名形式获取每一个字段的值
输出语句:
DBMS_OUTPUT.PUT_LINE(...);
3.异常
异常处理格式:
exception
when 异常类型1 then 处理语句
when 异常类型1 then 处理语句
两种常见的异常类型:
no_data_found 使用select into未返回行
TOO_MANY_ROWS 执行select into时,结果集超过一行
4.条件判断
格式:
if 条件 then
业务逻辑
elsif 条件 then //可有多个
业务逻辑
else
业务逻辑
end if; //必须有这一行
5.循环
1)无条件循环 //exit;停止循环
loop
--循环语句
exit when 循环停止条件; //停止循环, exit;可直接停止循环
end loop;
2)条件循环
while 条件
loop
...
end loop;
3)for循环
for 变量 in 起始值..终止值
loop
end loop;
6.游标 //类似一个变量(集合),存储多条记录,游标是系统为用户开设的一个数据缓冲区,存放 SQL 语句的执行结果可以把游标理解为 PL/SQL 中的结果集
1)在声明区声明游标,语法如下,声明游标:
cursor 游标名称 is sql语句 //sql语句只能是查询语句
cursor 游标名称(v_ownertypeid number) is sql语句 //带参数的游标的声明,在sql语句中可以直接使用参数
2)使用游标: //需要遍历才能得到游标中的每一条记录
不带参数游标
open 游标名称 //开启游标,
loop
fetch 游标名称 into 变量 //获取游标结果集中的下一个值
exit when 游标名称%notfound //没有下一个值则跳出循环
end loop;
close 游标名称 //结束游标
带参数游标
open cur_pricetable(2); //如果是带参数游标,在打开游标时传入参数,其他地方不变
for循环提取游标值: //不需要开启和关闭游标,for循环自动完成开启关闭
begin
for v_pricetable in cur_pricetable(3) //从游标中取出每一条记录赋值给变量v_pricetable
loop
dbms_output.put_line('价格:'||v_pricetable.price ||'吨位:'||v_pricetable.minnum||'-'||v_pricetable.maxnum );
end loop;
end ;
7.存储函数: //又称为自定义函数,可接收一个或多个参数,返回一个值,必须有返回值
定义结构:
CREATE [ OR REPLACE ] FUNCTION 函数名称
(参数名称 参数类型, 参数名称 参数类型, ...) //不需要指名参数类型长度
RETURN 结果变量数据类型 //指明返回值类型,也不需要指明长度
IS
变量声明部分;
BEGIN
逻辑部分;
RETURN 结果变量;
[EXCEPTION
异常处理部分]
END;
使用: //常用于查询语句中
函数名称(参数);
8.存储过程:
定义:存储过程是被命名的 PL/SQL 块,存储于数据库中,是数据库对象的一种。应用程序可以调用存储过程,执行相应的逻辑。
语法结构
CREATE [ OR REPLACE ] PROCEDURE 存储过程名称
(参数名 类型, 参数名 类型, 参数名 类型) //参数只指定类型,不指定长度
IS|AS
变量声明部分;
BEGIN
逻辑部分
[EXCEPTION
异常处理部分]
END;
过程参数的三种模式: //在参数表中指明
IN 传入参数(默认)
OUT 传出参数 ,主要用于返回程序运行结果 ,如 v_id out number
IN OUT 传入传出参数
有参数的存储过程语法结构
create or replace procedure pro_owners_add
(
v_name varchar2,
v_addressid number,
v_housenumber varchar2,
v_watermeter varchar2,
v_type number,
v_id out number //指定传出参数
)
is
begin
select seq_owners.nextval into v_id from dual; //给传出参数赋值
insert into T_OWNERS
values( v_id,v_name,v_addressid,v_housenumber,v_watermeter,sysdate,v_type );
commit;
end;
调用存储过程:
1)使用call关键字:
call pro_owners_add('赵伟',1,'999-3','132-7',1); //如果有传出参数,不能使用这种方式调用
2)在begin中调用:
declare
v_id number; //定义传出参数的变量
begin
pro_owners_add('王旺旺',1,'922-3','133-7',1,v_id); //直接传入参数接收传出值
DBMS_OUTPUT.put_line('增加成功,ID:'||v_id); //输出传出参数
end;
jdbc 调用存储过程
stmt=conn.prepareCall("{call pro_owners_add(?,?,?,?,?,?)}"); //通过连接获取java.sql.CallableStatement对象,也为statement子接口
stmt.set String(1, owners.get Name()); //设置参数同preparedStatement
stmt.set Long(2, owners.get Addressid());
...
stmt.registerOutParameter(6, OracleTypes.NUMBER); //注册传出参数的类型
stmt.execute(); //执行
id=stmt.getLong(6);//提取传出参数
和存储函数的区别:
1)存储函数中有返回值,且必须返回;而存储过程没有返回值,可以通过传出参数返回多个值
2)存储函数可以在 select 语句中直接使用,而存储过程不能。过程多数是被应用程序所调用
3)存储函数一般都是封装一个查询结果,而存储过程一般都封装一段事务代码。
9.触发器
定义:数据库触发器是一个与表相关联的、存储的 PL/SQL 程序。每当一个特定的数据操作语句(Insert,update,delete)
在指定的表上发出时,Oracle 自动地执行触发器中定义的语句序列。
语法结构:
CREATE [or REPLACE] TRIGGER 触发器名
BEFORE | AFTER
[DELETE ][[or] INSERT] [[or]UPDATE [OF 列名]]
ON 表名
[FOR EACH ROW ][WHEN(条件) ] //指定是否是行级触发器
declare
……
begin
:new.num:=:old.num+10; //不能再此处使用sql语句对表进行增删改,如update t_account set ...
End ;
伪记录变量:
:old 表示修改之前的值old.name,通过点可以获取字段值
:new 表示修改之后的值new.num1,通过点可以获取字段值
前置触发器(BEFORE):在commit语句之前被触发的触发器:在触发器中通过伪记录变量修改表中的记录
后置触发器(AFTER):在commit语句之后被触发的触发器:在触发器中不能修改表中的记录
行级触发器(FOR EACH ROW):影响了多少行数据就触发多少次
语句触发器:执行了几次sql语句就触发几次