cursor 游标:游标表示一个虚拟的结果集,相当于java中的引用(地址)
具体表示的是由select语句查询的虚拟的结果集的引用地址
使用游标可以对select语句查询的结果集进行遍历。
ResultSet res=null;
while(res.hashNext()){
res.getXxx("")
}
游标属性:
%found 该属性表示当前游标是否指向有效的一行,结果是一个Boolean 类型的。
这个属性一般用来判断是否结束当前游标的使用;
%notfound 与上面属性刚好相反,如指向行无效,返回true;
%rowcount 这个属性记录了游标取过记录的行数,也可以理解为当前游标所在的行数。
这个属性在循环的时候十分有效。
%isopen 顾名思义是表示游标是否处于打开的状态。
1.游标的使用
student表:
DECLARE
v_name student.sname%TYPE;
v_sex student.ssex%TYPE;
--定义游标,定义集合
CURSOR v_c IS SELECT sname,ssex FROM student;
BEGIN
--打开游标
OPEN v_c;
--遍历游标
LOOP
FETCH v_c INTO v_name,v_sex;
IF v_c%NOTFOUND THEN
EXIT; --退出遍历
END IF;
dbms_output.put_line(v_name||' '||v_sex);
END LOOP;
CLOSE v_c; --关闭游标
END;
输出:
2.使用for循环遍历游标
DECLARE
CURSOR v_c IS SELECT ssid,sname,ssex FROM student;
BEGIN
FOR v_r IN v_c LOOP
dbms_output.put_line(v_r.ssid||' '||v_r.sname||' '||v_r.ssex);
END LOOP;
END;
3.带参数的游标
--将男同学和女同学的数据拷贝到不同的两张表
--男同学:m_table
--女同学:t_table
--创建m_table表
create table m_table as select * from student where 1!=1;
--创建t_table表
create table t_table as select * from student where 1!=1;
DECLARE
--定义带参数的游标
CURSOR v_c(v_sex VARCHAR)
IS SELECT * FROM student WHERE ssex=v_sex;
BEGIN
--遍历游标
FOR v_r IN v_c('1') LOOP
--for v_r in v_c('0') loop
INSERT INTO m_table VALUES(v_r.ssid,v_r.sname,v_r.ssex,v_r.ssub,v_r.saddress,v_r.sentertime,v_r.age);
END LOOP;
COMMIT;
END;
--查看m_table、t_table
SELECT * FROM m_table;
SELECT * FROM t_table;
4.触发器介绍
--触发器
--触发器介绍
--触发器的作用:完成数据的完整性,完成数据完整性的自定义完整性
--数据自定义完整性:自己定义数据正确的规则。
--触发器:在数据库对某个表进行dml操作(dml触发器)的时候,自动去执行一段plsql块。
--触发器的构成:
--事件:dml操作(insert,update,delete)
--事件响应:plsql块
--响应时机:before | after
--触发器级别:语句级 | 行级
行级触发器:DML语句影响的每个行执行一次。(:NEW 和:OLD使用方法和意义,new 只出现在insert和update时,old只出现在update和delete时。在insert时new表示新插入的行数据,update时new表示要替换的新数据、old表示要被更改的原来的数据行,delete时old表示要被删除的数据。)
语句级触发器:DML语句执行一次,如果一条INSERT语句在TABLE表中插入500行,那么这个表上的语句级触发器只执行一次,而行级的触发器就要执行500次了。
/**
触发器的语法
create or replace trigger trigger_name
before
update
on student
for each row
declare
-- local variables here
begin
数据库curd操作;
end ;
**/
5.创建简单的触发器
CREATE OR REPLACE TRIGGER student_trigger
BEFORE --触发时机
INSERT --触发事件
ON student --事件源
DECLARE
BEGIN
dbms_output.put_line('对student执行dml操作');
END;
测试触发器: INSERT INTO student VALUES(100,'周润发','男','影视','香港',Sysdate,65);
输出:
6.完整的语句级dml触发器:
CREATE OR REPLACE TRIGGER student_trigger2
BEFORE
INSERT OR UPDATE OR DELETE --出发时间:dml操作
ON student --操作对象student表
DECLARE
BEGIN
dbms_output.put_line('---语句级dml触发器---'); --出发后执行动作
END;
--测试
INSERT INTO student VALUES(101,'周发发','男','影视','香港',Sysdate,65);
UPDATE student SET sname='周大发' WHERE ssid=101;
DELETE student WHERE ssid=101;
7.完整的行级dml触发器:
create or replace trigger student_trigger3
before
insert or update or delete
on student
for each row --行级触发器
declare
begin
dbms_output.put_line('=======dml行级触发器=======');
end;
--测试触发器:
insert into student values(103,'周润发',1,'影视','香港',SYSDATE,69); update student set
sname='周星星' where sno=103;
delete student where sno=103;
8.完成student表中数据操作的日志记录
日志表结构:用户 什么时间 什么操作 那条记录
触发中的常量:都是boolean类型 inserting deleting updating
触发器对象的属性
:new :new.colName (insert,update)
:old :old.colName (update,delete)
--创建日志表
CREATE TABLE stu_log(
lid NUMBER(5) PRIMARY KEY,
uname VARCHAR(30),
ldate DATE,
ltype VARCHAR(20),
sno NUMBER(5)
)
--定义主键策略,自增长模式
create sequence seq_lid
minvalue 1
maxvalue 999999999999999999999999999
start with 1
increment by 1
cache 20;
--定义student表的dml触发
CREATE OR REPLACE TRIGGER student_trigger4
AFTER
INSERT OR UPDATE OR DELETE
ON student
FOR EACH ROW
DECLARE
BEGIN
--插入时增加日志
IF inserting THEN
INSERT INTO stu_log VALUES(seq_lid.nextval,USER,SYSDATE,'增加',:new.ssid);
--:new.ssid 即学生表中新增数据的id
--修改时增加日志
ELSIF updating THEN
INSERT INTO stu_log VALUES(seq_lid.nextval,USER,SYSDATE,'修改',:old.ssid);
--:old.ssid即学生表中被修改数据的id
--删除时增加日志
ELSIF deleting THEN
INSERT INTO stu_log VALUES(seq_lid.nextval,USER,SYSDATE,'删除',:old.ssid); --被删除数据的id
END IF;
END;
--执行dml语句
insert into student values(105,'周1发',1,'影视','香港',SYSDATE,69);
update student set sname='周星星' where ssid=103;
delete student where ssid=102;
--查看日志表
select * from stu_log
输出:
其实还有一个部分时关于java调用orcale存贮过程和函数的,有时间补上,有兴趣的话可以看看这篇blog:
https://www.cnblogs.com/liushisaonian/p/7050872.html