快速学习Oracle触发器和游标


Posted in Oracle onJune 30, 2021
目录
  • 触发器:
    • 1、 创建一个用于记录用户操作的触发器
    • 2、创建一个当删除部门时,删除该部门下的所有雇员的触发器
    • 3、创建一个在account表插入记录之后,更新myevent数据表的触发器
    • 4、创建一个用于记录登录 DBA 身份用户的用户名和时间的触发器
  • 游标:
    • 1、使用隐式游标和 for 语句检索出职务是销售员(salesman)的雇员信息并输出
    • 2、员工工资上调20%,使用隐式游标输出上调工资的员工数量
    • 3、用显示游标和for语句检索出部门编号是30的雇员信息并输出
    • 4、声明游标检索员工信息,并使用%FOUND属性来判断
    • 5、创建游标完成数据转移,将fruit表中单价大于10的记录放到fruitage表中

 

触发器:

 

1、 创建一个用于记录用户操作的触发器

  创建一个dept_log数据表,并在其中定义两个字段(operate_tag varchar2(10),operate_time date),分别用来存储操作种类(插入,修改,删除)信息和操作日期。然后一个关于dept表的语句级触发器tri_dept,将用户对 dept 表的操作信息保存到dept_tag表中。

当任何时候从dept表中删除某个部门时,该触发器将从emp表中删除该部门的所有雇员。

-- 创建表
create table dept_log(
	operate_tag varchar2(10),
	operate_time date
);
create table dept(
	dname varchar2(20),
	dno number
);

-- 创建触发器
create or replace trigger tri_dept
before insert or update or delete
on dept
declare
	v_tag varchar2(10);
begin
	if inserting then
		v_tag:='插入';
	elsif updating then
		v_tag:='修改';
	elsif deleting then
		v_tag:='删除';
	end if;
	insert into dept_log values(v_tag, sysdate);
end tri_dept;
/

快速学习Oracle触发器和游标

 

2、创建一个当删除部门时,删除该部门下的所有雇员的触发器

当任何时候从dept表中删除某个部门时,该触发器将从emp表中删除该部门的所有雇员。

注意:所有的以sysdba登录的账户都不能创建触发器,因此需要在创建的用户下面创建触发器

-- 创建部门表
create table dept(
    deptno number not null,
    dname varchar(20) not null
);

-- 创建员工表
create table emp(
    emp_no number not null,
    emp_name varchar(20) not null,
    job varchar(20) not null,
    sal number  not null,
    deptno number not null
);

--插入数据
insert into dept values(10, '部门1');
insert into dept values(20, '部门2');
insert into emp values(1001, '员工1', '工作1', 5000, 10);
insert into emp values(1002, '员工2', '工作2', 7200, 10);
insert into emp values(1003, '员工3', '工作3', 6000, 10);
insert into emp values(1004, '员工4', '工作4', 5000, 20);
insert into emp values(1005, '员工5', '工作5', 7000, 20);
-- 创建触发器
create or replace trigger del_dept
before delete on dept
for each row
begin
	delete from emp where deptno = :old.deptno;
end;
/

快速学习Oracle触发器和游标


 

3、创建一个在account表插入记录之后,更新myevent数据表的触发器

创建了一个TRIG_INSERT的触发器,在向表account插入数据之后会向表myevent插入一组数据(表结构就不创建了…)

create or replace trigger trig_insert
after insert
on account
begin
	if inserting then
		insert into myevent values(1, 'after insert');
	end if;
end;
/

 

4、创建一个用于记录登录 DBA 身份用户的用户名和时间的触发器

以DBA 身份登录数据库,并创建一个名为db_log的数据表,用于记录登录用户的用户名和时间。
接着分别创建数据库启动和数据库关闭触发器,并向db_log数据表中插入记录,存储登录用户的用户名和操作时间。

--创建表
create table db_log(
	name varchar2(20),
	rtime timestamp
);

-- 创建触发器,用于记录用户登录
create or replace trigger trigger_startup
after startup
on database
begin
	insert into db_log values('user', sysdate);
end;
/

-- 创建触发器,用于记录用户退出
create or replace trigger trigger_shutdown
before shutdown
on database
begin
	insert into db_log values('xiuyan', sysdate);
end;
/

 

游标:

以下题目基于部门表和员工表:

-- 创建表
create table emp(
	empno number,
	ename varchar2(20),
	job varchar2(20),
	sal number,
	deptno number);
create table dept(
	deptno number,
	dname varchar2(20),
	loc varchar2(20));
	
-- 插入数据
insert into dept values(10,'account','new york');
insert into dept values(20,'salesman','chicago');
insert into dept values(30,'research','dallas');
insert into dept values(40,'operations','boston');
insert into emp values(1001,'mary','account',5000,10);
insert into emp values(2001,'smith','salesman',6000,20);
insert into emp values(3001,'kate','research',7000,30);

 

1、使用隐式游标和 for 语句检索出职务是销售员(salesman)的雇员信息并输出

begin
	for emp_record in(select empno, ename, sal from emp where job='salesman')
	loop
		dbms_output.put('雇员编号:'||emp_record.empno);
		dbms_output.put('; 雇员名称:'||emp_record.ename);
		dbms_output.put_line('; 雇员编号:'||emp_record.sal);
	end loop;
end;
/

快速学习Oracle触发器和游标


 

2、员工工资上调20%,使用隐式游标输出上调工资的员工数量

把 emp 表中销售员(即salesman)的工资上调20%,然后使用隐式游标 SQL 的 %ROWCOUNT 属性输出上调工资的员工数量。

begin
	update emp set sal=sal*(1+0.2) where job='salesman';
	if sql%notfound then
		dbms_output.put_line('没有雇员需要上调工资');
	else
		dbms_output.put_line('有'|| sql%rowcount ||'个雇员需要上调工资');
	end if;
end;
/

快速学习Oracle触发器和游标


 

3、用显示游标和for语句检索出部门编号是30的雇员信息并输出

declare
	cursor cur_emp is
	select * from emp where deptno = 30;
begin	
	for emp_record in cur_emp
	loop
		dbms_output.put('雇员编号:'||emp_record.empno);
		dbms_output.put('; 雇员名称:'||emp_record.ename);
		dbms_output.put_line('; 雇员职务:'||emp_record.job);
	end loop;
end;
/

快速学习Oracle触发器和游标


 

4、声明游标检索员工信息,并使用%FOUND属性来判断

声明一个游标,用于检索指定员工编号的雇员信息,然后使用游标的%FOUND属性来判断是否检索到指定员工编号的雇员信息。

declare
	v_ename varchar2(50);
	v_job varchar2(50);
	cursor cur_emp is
	select ename, job from emp where empno = &empno;
begin
	open cur_emp;
	fetch cur_emp into v_ename, v_job;
	if cur_emp%found then
		dbms_output.put('雇员编号:'||v_ename ||',职务是:'||v_job );
	else
		dbms_output.put('无数据记录');
	end if;
end;
/

快速学习Oracle触发器和游标


 

5、创建游标完成数据转移,将fruit表中单价大于10的记录放到fruitage表中

创建 fruit 表并插入数据

-- 创建水果表
create table fruit(
	f_id    varchar2(10)    not null,
	f_name  varchar2(255)  	not null,
	f_price  number (8,2)  	not null
);

--插入数据
insert into fruit values  ('a1', 'apple',5.2);
insert into fruit values ('b1','blackberry', 10.2);
insert into fruit values ('bs1','orange', 11.2);
insert into fruit values('bs2','melon',8.2);
insert into fruit values ('t1','banana', 10.3);
insert into fruit values ('t2','grape', 5.3);
insert into fruit values ('o2','coconut', 9.2);

创建表fruitage,表fruitage和表fruit的字段一致,利用以下语句创建:

create table fruitage as select * from fruit where 2=3;
-- 如果WHERE后面的条件为真,则复制表时把数据也一起复制。
-- 不加默认会复制数据。

创建游标,完成数据转移,将fruit表中,单价大于10的记录放到fruitage表中。

declare 
	v_id fruit.f_id %TYPE;
	v_name fruit.f_name %TYPE;
	v_price fruit.f_price %TYPE;
	cursor frt_cur is
	select f_id, f_name, f_price from fruit where f_price>10;
begin
	open frt_cur;
	loop
		fetch frt_cur into v_id, v_name, v_price;
			if frt_cur%found then
				insert into fruitage values(v_id, v_name, v_price);
			else
				dbms_output.put_line('已取出所有数据,共有'||frt_cur%ROWCOUNT||'条记录');
			exit;
			end if;
	end loop;
	close frt_cur;
end;
/

快速学习Oracle触发器和游标

到此这篇关于Oracle触发器和游标练习题的文章就介绍到这了,更多相关Oracle触发器和游标内容请搜索三水点靠木以前的文章或继续浏览下面的相关文章希望大家以后多多支持三水点靠木!

Oracle 相关文章推荐
Oracle 数据仓库ETL技术之多表插入语句的示例详解
Apr 12 Oracle
Oracle 区块链表创建过程详解
May 15 Oracle
Oracle11g r2 卸载干净重装的详细教程(亲测有效已重装过)
Jun 04 Oracle
DBCA命令行搭建Oracle ADG的流程
Jun 11 Oracle
Oracle 死锁的检测查询及处理
Sep 25 Oracle
oracle重置序列从0开始递增1
Feb 28 Oracle
oracle删除超过N天数据脚本的方法
Feb 28 Oracle
详解SQL的窗口函数
Apr 21 Oracle
oracle数据库去除重复数据
May 20 Oracle
Oracle锁表解决方法的详细记录
Jun 05 Oracle
Oracle中日期的使用方法实例
Jul 07 Oracle
使用Oracle跟踪文件的问题详解
SQL模糊查询报:ORA-00909:参数个数无效问题的解决
ORACLE查看当前账号的相关信息
DBCA命令行搭建Oracle ADG的流程
ORACLE数据库应用开发的三十个注意事项
Jun 07 #Oracle
Oracle创建只读账号的详细步骤
Oracle11g R2 安装教程完整版
You might like
透析PHP的配置文件php.ini
2006/10/09 PHP
PHP 木马攻击防御技巧
2009/06/13 PHP
PHP获取文件后缀名的三个函数
2012/10/15 PHP
set_include_path和get_include_path使用及注意事项
2013/02/02 PHP
ThinkPHP的cookie和session冲突造成Cookie不能使用的解决方法
2014/07/01 PHP
深入浅出php socket编程
2015/05/13 PHP
php计算整个目录大小的方法
2015/06/01 PHP
简单谈谈php浮点数精确运算
2016/03/10 PHP
php进程间通讯实例分析
2016/07/11 PHP
PHP实现小偷程序实例
2016/10/31 PHP
jQuery 选择表格(table)里的行和列及改变简单样式
2012/12/15 Javascript
jQuery中;function($,undefined) 前面的分号的用处
2014/12/17 Javascript
jquery调取json数据实现省市级联的方法
2015/01/29 Javascript
js模仿java的Map集合详解
2016/01/06 Javascript
使用jsonp实现跨域获取数据实例讲解
2016/12/25 Javascript
微信小程序实现点击图片旋转180度并且弹出下拉列表
2018/11/27 Javascript
JS快速实现简单计算器
2020/04/08 Javascript
jQuery+ThinkPHP实现图片上传
2020/07/23 jQuery
JavaScript中作用域链的概念及用途讲解
2020/08/06 Javascript
[01:14]DOTA2 7.22版本新增神杖效果展示(智力英雄篇)
2019/05/29 DOTA
Python标准库os.path包、glob包使用实例
2014/11/25 Python
hmac模块生成加入了密钥的消息摘要详解
2018/01/11 Python
python使用Tesseract库识别验证
2018/03/21 Python
对Python 简单串口收发GUI界面的实例详解
2019/06/12 Python
Python交互式图形编程的实现
2019/07/25 Python
Pytorch之Variable的用法
2019/12/31 Python
Python3 io文本及原始流I/O工具用法详解
2020/03/23 Python
Pyspark读取parquet数据过程解析
2020/03/27 Python
详解Python中string模块除去Str还剩下什么
2020/11/30 Python
英国领先的男士服装和时尚零售商:Burton
2017/01/09 全球购物
最新的互联网创业计划书
2014/01/10 职场文书
庆元旦迎新年广播稿
2014/02/18 职场文书
法学自荐信
2014/06/20 职场文书
贷款工资证明范本
2015/06/12 职场文书
幼儿园托班开学寄语(2016秋季)
2015/12/03 职场文书
Python闭包的定义和使用方法
2022/04/11 Python