SQL语言共分为四大类:数据查询语言DQL,数据操纵(增删改)语言DML,数据定义语言DDL()表、视图、索引、同义词、聚簇等DDL操做是隐性提交的!不能rollback),数据控制语言DCL()授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等。node
DAY1sql
--oracle的数据类型数据库
--字符类型:session
--char : 定长,最大2000字符oracle
--例子:char(10) '张三',后6位空格补全 ide
--特色:查询速度极快函数
--varchar2 : 变长,最大4000字符oop
--例子:varchar2(10) '张三'fetch
--特色:节省空间ui
--clob : 字符型大对象,最大4G
--数字类型:
--number:既能够表示整数也能够表示小数
--范围:-10e38-10e38
--整数:number(3),表示一个3位的整数,范围-999-999
--小数:number(5,2),表示一个小数,该小数一共5位,其中小数部分占2位,范围:-
999.99-999.99之间
--日期类型:
--date:包含年月日时分秒
--timestamp:oracle对date类型的扩展,比date更加精确
--二进制数据类型:
--blob:二进制数据,能够存放图片,音频,视频,范围4G
--通常不会把图片和声音存放在数据库中,一般的作法是将图片或音频的路径存在数据库
中(char/varchar2),若是保密性要求很是高,能够存放到数据库中。
--SQL语言:结构化查询语言
--建表
--表名和列名的命名规则:
--1,必须以字母开头
--2,长度不能超过30个字符
--3,不能使用oracle关键字和保留字
--4,只能使用以下字符:A-Z,a-z,0-9,#$等
--5,oracle不要使用中文
--建立学生表
create table student(
stuno number(4) primary key,
stuname char(50),
gender char(3),
age number(3),
birthday date,
jxj number(7,2),
classno number(3),
--外键,classno是外键,该列的数据受classes表的cno的约束(classno的值必须来自于
classes的cno字段的值)
constraint fk_classes foreign key(classno) references classes(cno)
)
--建立班级表:班级编号,班级名称
create table classes(
cno number(3) primary key,
cname varchar2(100)
)
--oracle中的约束
SQL 使用单引号来环绕文本值(大部分数据库系统也接受双引号)。若是是数值,请不要使用引号。
--在oracle中,约束包括:not null,unique,primarykey,foreign key,check五种
--1,not null:非空
create table tab1(
tid number(3) not null,
tname varchar2(20)
)
--2.unique:惟一
create table tab2(
tid number(2) not null,
sfz char(18) unique
)
--primary key :主键约束(非空+惟一)
--一个表中只能有一个主键,可是主键能够由多个列组成(联合主键)
create table tab3(
tid number(5) primary key,
tname varchar2(50),
address varchar2(100)
)
create table tab4(
stuno number(5),
school varchar2(50),
--address varchar2(100) primary key,
primary key(stuno,school)--联合主键
)
--check约束
create table tab5(
tid number(5) primary key,
age number(3) check (age>0 andage<=120),
gender char(3) default '男' check(gender='男' or gender='女') ,
jxj number(7,2) default 0.0
)
--foreign key :外键约束
DAY2
--做业:
--商店售货系统:
--现有一个商店的数据库,记录客户及其购物状况,由下面三个表组成:
--商品表goods(商品编号,商品名称,单价,商品类别,供应商)
--客户表customer(客户编号,姓名,地址,电子邮件,性别,身份证号码)
--购买表perchase(客户编号,商品编号,购买数量,购买时间)
--要求:
--每一个表都要有主键
--相关联的表有外键
--客户姓名不能为空,身份证惟一,电子邮件惟一
--单价大于0,购买数量在1-50之间
--客户性别只能是男或女,默认男
create table goods(
gid number(5) primary key,
gname varchar2(100),
price number(10,2) check (price>0),
gtype varchar2(100),
provider varchar2(100)
);
create table customer(
cid number(5) primary key,
cname char(20) not null,
address varchar2(100),
email varchar2(50) unique,
gender char(3) default '男'check(gender='男' or gender='女'),
sfz char(18) unique
);
create table perchase(
cid number(5),
gid number(5),
buyaccount number(2) check(buyaccount>0 andbuyaccount<=50),
buytime date,
primary key(cid,gid,buytime),
constraint fk_goods foreign key(gid)references goods(gid),
constraint fk_customer foreign key(cid)references customer(cid)
);
--添加数据
--查看表结构
desc student
insert into student(stuname,stuno,gender,age)values ('李四',333,'男',20)
--向所有字段添加数据,此时字段名能够省略
--添加空值
insert intostudent--(stuno,stuname,gender,age,birthday,jxj,classno)
values
(112,'张三2','男',22,'01-10月-98',null,1)
--修改默认的日期格式(临时)
alter session set nls_date_format='yyyy-mm-dd';
insert into student
values
(113,'张三2','男',22,'1998-2-16',100,1)
--修改数据
update student set stuname='李思思',gender='女',age=18where stuno=333
--有奖学金的同窗奖金翻倍
update student set jxj=jxj*2 where jxj isnot null;
--没有奖学金的同窗发50
update student set jxj=50 where jxj is null;
--注意:若是update语句中没有where条件,则更新所有数据
--删除数据
delete from student where stuno=1;
--注意:若是delete语句中没有where条件,则删除所有数据
--还有一种删除所有数据的方法
truncate table student;
--小结:清空表有两种方式:1,delete fromstudent;2,truncate table student
--两种方式的区别:
--1,delete的速度慢,truncate速度快
--2,delete删除的数据能够恢复,由于写了日志,而truncate删除的数据没有写日志,不能恢复
--3,若是表中的数据很大,而且肯定要完全删除数据,此时可使用truncate,不然就使用delete
--删除表结构
drop table student;
--查询
--查询所有数据
select * from emp;
--查询部分字段(指定的列)
select empno,sal,ename,job from emp;
--查询所有职位
select job from emp;
--去掉重复行
select distinct job from emp;
select distinct deptno from emp;
--查询KING的信息
SELECT * from EMP where ename='KING';
--oracle语句不区分大小写,可是数据要区分
--查询部门编号为10号部门员工的姓名,上级,职位,部门编号
select ename,mgr,job,deptno from emp wheredeptno=10;
--查询工资在1000到2000之间的员工
select * from emp where sal>=1000 andsal<=2000
select * from emp where sal between 1000and 2000
--查询30号部门工资在1000到2000之间的员工
select * from emp where sal between 1000and 2000 and deptno=30
--查询工资低于1000和高于3000的员工
select * from emp where sal<1000 orsal>3000;
--查询1982,1,1,年以后入职的员工
select * from emp wherehiredate>='1982-01-01';
--查询1981年入职的员工
select * from emp where hiredate between'1981-01-01' and '1981-12-31';
--查询每一个员工的年薪(as能够省略)
select (sal+nvl(comm,0))*12 as 年薪,ename,sal,commfrom emp;
--说明:nvl(comm,0)的含义是:若是comm为null,则使用0参与运算
--模糊查询
--like关键字
--%:表示匹配0-N个字符
--_:表示匹配1个字符
--查询名字首字母为M的员工
select ename from emp where ename like'M%';
--查询名字第三个字母为A的员工
SELECT * from emp where ename like '__A%';
--查询姓名为KING,SCOTT,MILLER的员工的信息
select * from emp where ename='KING' ORENAME='SCOTT' OR ENAME='MILLER'
select * from emp where ename in('KING','SCOTT','MILLER')
--在where条件中,使用in比使用or效率高
--查询没有上级的员工
select * from emp where mgr is null;
--查询工资高于1000或者职位为MANAGER的员工,同时知足其姓名首写字母为J
select * from emp where (sal>1000 orjob='MANAGER') and ename like 'J%';
--排序
--按照员工编号有小到大排序(asc能够省略)
select * from emp order by empno asc;
--按照员工编号由大到小
select * from emp order by empno desc;
--查询员工姓名,工资,按照工资由高到低排序
select ename,sal from emp order by saldesc;
--查询员工信息,按照部门编号升序而员工工资降序排列
select * from emp order by deptno,sal desc;
--查询员工信息,按照部门编号降序员工入职时间升序
select * from emp order by deptnodesc,hiredate;
--使用别名排序
select ename, (nvl(comm,0)+sal)*12 年薪 from emporder by 年薪 desc
--数据分组:max,min,avg,sum,count
--查询最高工资是多少
select max(sal) from emp;
--查询最高工资和最低工资,平均工资,总工资是多少
select max(sal),min(sal),avg(sal),sum(sal)from emp;
--查询公司员工人数
select count(*) from emp;
--查询工资最低的员工信息
--select *,min(sal) from emp;
--子查询
select * from emp where sal=(selectmin(sal) from emp);
--查询工资高于平均工资的员工
select * from emp where sal>(selectavg(sal) from emp);
--把工资低于平均工资的,入职时间在1982年以前的员工,工资增长10%
update emp set sal=sal+sal*0.1 wherehiredate<'1982-01-01' and sal<(select avg(sal) from emp);
--分组
--group by:用于对查询结果分组
--查询每一个部门的最高工资和最低工资
select max(sal),min(sal),deptno,sal fromemp group by deptno;
--查询每一个部门的每种职位的最高工资和最低工资
select min(sal),max(sal),deptno,job fromemp group by deptno,job order by deptno;
--having:用于分组后结果的筛选
--查询平均工资低于2000的部门及其平均工资
select avg(sal) 部门平均工资,deptnofrom emp group by deptno having avg(sal)<2000;
--小结:
--1.若是使用group by,那么在select后面只能跟分组函数和groupy by后面跟的字段
--2.分组后的筛选用having而不能用where
--3.顺序:groupby,having,order by
查询emp 每一个部门最高薪资大于2800的员工记录select e.* from emp e,(select deptno,max(t.sal)m from(select * from emp where(sal>2800))t group by deptno) d where (e.deptno =d.deptno and e.sal = d.m);
DAY3
--多表查询
--查询员工姓名及所在部门名称
--dept表和emp表作笛卡尔乘积
select * from emp,dept;
--就笛卡尔乘积的结果进行筛选
select * from emp,dept whereemp.deptno=dept.deptno;
--查询指定的列
select emp.ename,dept.dname from emp,deptwhere emp.deptno=dept.deptno;
--给表取别名
select e.ename,d.dname from emp e,dept dwhere e.deptno=d.deptno;
select e.ename,d.dname from emp e join deptd on e.deptno=d.deptno;
--数据库笛卡尔乘积的原则:
--若是n张表作乘积,至少须要n-1个条件
--查询10号部门的部门名称,员工姓名,工资
select d.dname,e.ename,e.sal from empe,dept d where e.deptno=d.deptno and d.deptno=10;
select d.dname,e.ename,e.sal from emp ejoin dept d on e.deptno=d.deptno and d.deptno=10;
--查询员工姓名,工资,及工资的级别
select e.ename,e.sal,s.grade from empe,salgrade s where e.sal between s.losal and s.hisal;
--查询员工姓名,工资,部门名称,按照部门编号排序
select e.ename,e.sal,d.dname from empe,dept d where e.deptno=d.deptno order by e.deptno desc;
--查询scott的上级的姓名
select a.ename,b.ename 上级名字 from empa,emp b where a.mgr=b.empno and a.ename='SCOTT';
--联合查询
--库存表
create table kucun(
kid number(5) primary key,
gname varchar2(100),--产品名称
kaccount number(5)--库存数量
);
--订单表
create table dingdan(
did number(5) primary key,
gname varchar2(100),--产品名称
daccount number(5)--数量
) ;
--产品表
create table chanpin(
cid number(5) primary key,
gname varchar2(100),--产品名称
price number(7,2)--单价
);
insert into chanpin values(1,'电脑',2000);
insert into chanpin values(2,'苹果',5);
insert into chanpin values(3,'手机',7000);
insert into kucun values(1,'苹果',100);
insert into kucun values(2,'鼠标',1000);
insert into kucun values(3,'门',10);
insert into dingdan values(1,'苹果',5);
insert into dingdan values(2,'键盘',50);
insert into dingdan values(3,'手机',10);
--查询能够出货的产品(某个产品既有订单,又有库存)
select k.*,d.* from kucun k,dingdan d wherek.gname=d.gname;
--查询全部库存产品,以及那些库存产品有了订单???????(使用联合查询)
/*
联合查询:join....on....
join的做用是将两个或两个以上的表记录横向链接起来,on的做用是设置查询条件,将无用的记录过滤掉
分类:
1.内部联接:[inner] join
2.左外部联接 left [outer]join
3.右外部联接 right [outer]join
4.彻底外部联接 full [outer]join
5.交叉联接 cross join
*/
--1.内部联接:[inner] join
--内部联接只显示符合条件的记录
--查询能够出货的产品(某个产品既有订单,又有库存)
select * from kucun k inner join dingdan don k.gname=d.gname;
select * from dingdan k inner join kucun don k.gname=d.gname;
--三张表
select * from dingdan d join kucun k ond.gname=k.gname join chanpin c on d.gname=c.gname;
select k.*,d.*,c.* from kucun k,dingdand,chanpin c where k.gname=d.gname and d.gname=c.gname;
--2.左外部联接 left [outer]join
--显示左边表中全部的记录,以及右边表中符合条件的记录
--查询全部库存产品,以及哪些库存产品有了订单
select * from kucun k left outer joindingdan d on k.gname=d.gname;
--3.右外部联接 right [outer]join
--查询右边表中全部的记录,以及左边表中符合条件的记录
--查询全部库存产品,以及哪些库存产品有了订单
select * from dingdan d right outer joinkucun k on d.gname=k.gname;
--4.彻底外部联接 full [outer]join
--查询所有数据,包括符合条件的和不符合条件的
--查询全部的库存和订单,显示哪些库存没有订单,以及哪些订单没有库存
select * from dingdan d full join kucun kon d.gname=k.gname;
--5.交叉联接 cross join(笛卡尔乘积):没有on来设置条件
select * from kucun cross join dingdan;
/*集合操做:并集,交集,差集
并集(union):union的做用是将两个或多个查询的结果合并为一个结果集。该结果集包含联合查询中的全部查询的所有行,
union运算不等同于join运算,join是将两个或多个数据表的字段进行水平合并,通常来讲,合并后的字段数会增长,
而union是将多个查询结果上下叠加,合并后字段数不会增长,但记录总数会增长。
*/
create table stuInfo(
stuid number(5) primary key,
stuname varchar2(50)
);
create table userinfo(
userid number(5) primary key,
username varchar2(50)
);
insert into stuinfo values(1,'张三');
insert into stuinfo values(2,'张三三');
insert into stuinfo values(3,'李四');
insert into userinfo values(1,'张三');
insert into userinfo values(2,'张三三');
insert into userinfo values(3,'王五');
--查询全部注册了的和未注册的学生
--合并了相同的结果
select * from stuinfo where stuid=3 unionselect * from userinfo where userid=3;
--不合并相同结果
select * from stuinfo union all select * from userinfo;
--交集(intersect):合并两个结果集,返回两个查询相同的全部非重复的值
--查询两个表中都有的信息
select * from stuinfo intersect select *from userinfo;
--差集(minus):合并两个结果集,该结果集比较两个查询的结果,从左查询中返回右查询中没有的非重复的值
--查询没有注册的学生
select * from stuinfo minus select * fromuserinfo;
--子查询
--子查询是指嵌入在其余sql语句中的select语句,也叫做嵌套查询
--单行子查询:只返回一行数据的子查询
--查询与SCOTT相同部门的员工
select deptno from emp where ename='SCOTT';
select * from emp where deptno=(selectdeptno from emp where ename='SCOTT');
--多行子查询:子查询返回多行数据
--查询和部门编号为10号的部门职位相同的员工的信息
select job from emp where deptno=10;
select * from emp where job in(select job from emp where deptno=10);
--all关键字
--查询工资比30号部门全部员工都高的员工信息
select max(sal) from emp where deptno=30;
select * from emp where sal>(selectmax(sal) from emp where deptno=30);
--all关键字
select * from emp where sal>all(selectsal from emp where deptno=30);
--从效率上来说,第一种方式要高的多
--any关键字
--查询工资比30号部门任意一个员工工资高的员工信息
select * from emp where sal>(selectmin(sal) from emp where deptno=30);
--使用any关键字
select * from emp where sal>any(selectsal from emp where deptno=30);
--多列子查询:子查询返回多列
--查询跟SCOTT相同部门和职位的员工信息
select * from emp where (job,deptno)=(select job,deptno from emp whereename='SCOTT');
--查询工资高于本身所在部门平均工资的员工信息
--1.查询各个部门的部门编号和平均工资
select deptno,avg(sal) 平均工资 from empgroup by deptno;
--2.将上面的查询结果当成一张表,跟emp表作多表查询
select * from emp e,(select deptno,avg(sal) 平均工资 from emp group bydeptno) a
where e.deptno=a.deptno and e.sal>a.平均工资;
--事务
/*
事务用于保证数据的一致性,由一组相关的dml(增删改)语句组成,该组成的语句要么所有成功,要么所有失败。
事务是很必要的,好比,网上转帐系统,就是典型的须要用事务来处理。
*/
--设置保存点
savepoint a;
--取消部分事务
rollback to a;
--取消所有事务
rollback;
/*
事务的实现:锁
当执行事务的时候,oralce会在被做用的表上加锁,防止其余用户改表结构。
*/
/*
事务的提交:commit
执行commit以后,会确认事务的变化,事务结束,删除保存点,释放锁。
*/
--函数(库)
--字符函数
--lower(char):将字符串转换为小写
--以小写字母显示全部员工姓名
select lower(ename) from emp;
--upper(char)
--以大写字母显示员工姓名
select upper(lower(ename)) from emp;
--length(char):返回字符串长度
--查询名字为4个字母的员工
select * from emp where length(ename)=4;
--substr(char,m,n):截取子串,从第m个字符开始,n表示截取的长度
--显示全部员工姓名的前三个字母
select substr(ename,1,3) from emp;
--以首字母大写,其他字母小写的方式显示员工姓名
select upper(substr(ename,1,1)) from emp;--首字母大写
select lower(substr(ename,2,length(ename)-1))from emp;--其他字母小写
select upper(substr(ename,1,1))||lower(substr(ename,2,length(ename)-1))from emp;--合并
selectINITCAP(ename) from emp;
--replace(char,c1,c2)
--用哈哈替换姓名中全部的字母A
select replace(ename,'A','哈哈') FROMEMP;
--数学函数
--round(n,m):执行四舍五入,m能够省略,若是省略m,则四舍五入到整数,若是m是正数,则四舍五入到小数点的m位后,
--若是m是负数,则四舍五入到小数点的m位前
--保留工资小数点后一位,四舍五入
select ename,round(sal,1) from emp;
--trunc(n,m):截取,不会四舍五入,多的位数直接舍弃
--保留工资小数点后一位,多的截取
select ename,trunc(sal,1) from emp;
--floor(n):向下取整
select floor(sal) from emp;
--ceil(n):向上取整
select ceil(sal) from emp;
--mod(m,n)取模
--计算10÷3的余数
select mod(10,3) from dual;--dual是一张虚拟表
--查询全部员工的日薪
select ename, ceil(sal/21.75) from emp;
select ename,trunc(sal/21.75) from emp;
select ename,round(sal/21.75) from emp;
--日期函数
--sysdate
select sysdate from dual;
--将字符串转换为日期
select to_date('1982','yyyy') from dual;
--将日期转换为字符串
select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') fromdual;
--add_months(d,n):加月份
--查询已经转正的员工(试用期三个月计算)
select * from emp whereadd_months(hiredate,3)<sysdate;
select * from emp whereadd_months(hiredate,4)<to_date('1982-1-1','yyyy-mm-dd');
--查询入职满5年的员工
select * from emp whereadd_months(hiredate,5*12)<sysdate;
--查询每一个员工的入职天数
select ename,trunc(sysdate-hiredate) 入职天数 fromemp;
--last_day(d):返回指定日期所在月份的最后一天
select ename,last_day(hiredate) from emp;
--查询每月倒数第三天入职的员工
select * from emp wherelast_day(hiredate)-2=hiredate;
--系统函数:sys_context('userenv',选项)
/*
选项能够是:
language:当前系统语言
db_name:当前数据库名字
nls_date_format:当前会话的日期格式
session_user:当前会话所对应的数据库用户名
current_schema:当前方案名
host:主机名
*/
select sys_context('userenv','host') fromdual;
4. 选择雇用时间在1981-02-01到1981-05-01之间的员工姓名,职位(job)和雇用时间,按从早到晚排序.
select ename "姓名",job "职位",hiredate "雇佣时间"
from emp where hiredate between to_date('1981-02-01','YYYY-MM-DD')and to_date('1981-05-01','YYYY-MM-DD')
order by hiredate asc
6. 选择在1987年雇用的员工的姓名和雇用时间
select ename "姓名",hiredate"雇佣时间" from emp whereto_char(hiredate,'YYYY')='1987'
取出雇用时间的年份且转换为字符形式;而后与'1987'比较
select ename "姓名",hiredate"雇佣时间" from emp where to_char(hiredate,'MM')='04'
select ename "姓名",hiredate"雇佣时间" from emp where to_char(hiredate,'MM')='4'
前者是能够的,后者不可
DAY4
/*
pl/sql
procedure language/sql
是oracle在标准的sql语言上的扩展,能够定义变量,可使用条件分之和循环,容许使用例外处理各类错误。
分类:
块
过程
函数
包
触发器
编码规范:
变量:建议使用v做为前缀 v_name
常量:建议使用c做为前缀 c_pai
游标:建议使用cursor做为后缀 user_cursor
例外:建议使用e做为前缀 e_exception
*/
/*
块
块是pl/sql的基本单元
组成:定义部分,执行部分,例外处理部分
基本语法:
declare
定义部分
begin
执行部分
exception
例外处理部分
end;
*/
set serveroutput on;--打开输出选项
--helloworld
begin
dbms_output.put_line('hello world');
end;
--输入员工编号,获取员工姓名并输出
declare
v_ename varchar2(10);
v_job varchar2(20);
begin
select ename,job into v_ename,v_job from emp where empno=&n;
dbms_output.put_line('员工的姓名是:'||v_ename||',职位是:'||v_job);
end;
--处理输入不存在的员工编号
declare
v_ename varchar2(10);
begin
select ename into v_ename from emp whereempno=&n;
dbms_output.put_line('员工的姓名是:'||v_ename);
--处理例外
exception
when no_data_found then
dbms_output.put_line('输入的编号不存在');
end;
--(存储)过程
create procedure pro1 is
begin
insert into stuinfo values(5,'哇哈哈');
end;
--输入员工编号,新的工资,更新员工工资
create or replace procedure pro2(enonumber,newsal number) is
begin
update emp set sal=newsal where empno=eno;
end;
--函数
--输入员工姓名,返回员工年薪
create or replace function fun1(empname varchar2)
return number is nx number(7,2);
begin
select (sal+nvl(comm,0))*12 into nx from emp where ename=empname;
return nx;
end;
--函数的调用
var a number;
call fun1('SMITH') into:a;
--包:包是过程和函数在逻辑上的组合。由包规范和包体两部分组成。
--定义包,放入一个过程和一个函数
create or replace package pac1 is
procedure updateuname(usersidnumber,newname varchar2);
function getusernamebyid(usersid number)return varchar2;
end;
--建立包体,实现上面的包
create or replace package body pac1 is
procedure updateuname(usersidnumber,newname varchar2) is
begin
update userinfo set username=newname where userid=usersid;
end;
function getusernamebyid(usersid number)return varchar2 is
returnname varchar2(10);
begin
select username into returnname from userinfo where userid=usersid;
return returnname;
end;
end;
--调用
var b varchar2;
call pac1.getusernamebyid(1) into:b;
--练习:建立包规范,包含一个过程(输入员工编号,新的职位,修改该员工职位),
--一个函数(输入员工编号,获取员工日薪),实现该包规范的包体
--触发器:当发生特定事件的时候,触发器自动执行
--向userinfo表中添加一条数据时,提示“添加了一条数据”
create or replace trigger trig1
after insert on userinfo
begin
dbms_output.put_line('添加了一条数据');
end;
--语句级触发
create or replace trigger trig2
after update on userinfo
begin
dbms_output.put_line('修改了一条数据');
end;
--行级触发
create or replace trigger trig2
after update on userinfo
for each row--表示是行级触发
begin
dbms_output.put_line('修改了一条数据');
end;
--orcle中,自动增加,是经过序列实现的
create sequenceseq_stuid
start with 1
increment by 1
maxvalue 99999
cache 20;
--向stuinfo表中添加数据
insert into stuinfo values(seq_stuid.nextval,'张三','stu001');
insert into stuinfovalues(seq_stuid.nextval,'张三2','stu002');
insert into stuinfo values(seq_stuid.nextval,'张三3','stu003');
insert into stuinfovalues(seq_stuid.nextval,'张三4','stu004');
--触发器实例之一:实现触发器:每次向stuinfo表中添加数据以前,自动从序列产生一个数字,填入stuid
create or replace trigger trig_stuid
before insert on stuinfo
for each row
declare
newid stuinfo.stuid%type;--newid的数据类型是stuinfo表中的stuid字段的类型
begin
select seq_stuid.nextval intonewid from dual;
:new.stuid:=newid;--:new表示新插入的那条数据
end;
--实现id自动增加
insert into stuinfo(stuname,stuno)values('李四','stu110');
--触发器实例之二:写日志
--建立日志表,该表记录对stuinfo表的操做
create table stuinfolog(
operuser varchar2(20),--操做的帐户
opertype varchar2(10),--操做的类型:insert,update,delete
operdate date--时间
)
--建立写日志的触发器
create or replace trigger trig_stuinfo
after insert or update or delete onstuinfo
begin
if insertingthen
insert into stuinfologvalues(user,'insert',sysdate);
elsif updatingthen
insert into stuinfolog values(user,'update',sysdate);
elsif deletingthen
insert into stuinfolog values(user,'delete',sysdate);
end if;
end;
--变量
--变长字符串
v_name varchar2(10);
--定义小数,初始值为3.14
c_pai number(3,2):=3.14;
--日期类型
c_date date;
--定义布尔类型,不能为空,初始值为false
v_b boolean not null default false;
--输入员工编号,输出员工姓名,工资,我的所得税,用块实现
declare
v_ename emp.ename%type;
v_sal emp.sal%type;
v_tax number(5,2);
c_rate number(3,2):=0.03;
begin
select ename,sal into v_ename,v_sal from emp where empno=&n;
--计算税
v_tax:=v_sal*c_rate;
dbms_output.put_line('姓名:'||v_ename||',工资:'||v_sal||',税:'||v_tax);
end;
--游标
--输入部门编号,输出该部门的员工姓名,职位,工资
declare
--定义游标类型
type emp_cursor_type is ref cursor;
--定义游标变量
emp_cursor emp_cursor_type;--e_name varchar2(10)
--定义其余变量
v_ename emp.ename%type;
v_job emp.job%type;
v_sal emp.sal%type;
begin
--使用游标指向查询结果
open emp_cursor for select ename,job,sal from emp where deptno=&n;
--循环取出
loop
fetch emp_cursor into v_ename,v_job,v_sal;
exit when emp_cursor%notfound;
dbms_output.put_line('姓名:'||v_ename||',工资:'||v_sal||',职位:'||v_job);
endloop;
end;
--条件分之语句
--1.if-then
--输入员工姓名,若是员工工资低于1000,就给加薪10%
create or replace procedure pro3 (empnamevarchar2) is
v_sal emp.sal%type;
begin
select sal into v_sal from emp where ename=empname;
--判断
ifv_sal<1000 then
update emp set sal=sal*1.1 where ename=empname;
endif;
end;
--2.IF-THEN-ELSE
--输入员工姓名,若是该员工奖金为0,则奖金变为50,若是奖金不为0,则增长80
create or replace procedure pro4 (empnamevarchar2) is
v_comm emp.comm%type;
begin
select comm into v_comm from emp where ename=empname;
ifv_comm<>0 then
update emp set comm=comm+80 where ename=empname;
else
update emp set comm=50 where ename=empname;
endif;
end;
--if-then-elsif-else
--输入员工姓名,若是职位是CLERK,则工资增长50,若是职位是MANAGER,则工资增长80,其余职位,工资增长20
create procedure pro5(empname varchar2) is
v_job emp.job%type;
begin
select job into v_job from emp where ename=empname;
ifv_job='CLERK' then
update emp set sal=sal+50 where ename=empname;
elsif v_job='MANAGER' then
update emp set sal=sal+80 where ename=empname;
else
update emp set sal=sal+20 where ename=empname;
endif;
end;
--循环
--loop:相似于do-while
--输入用户名,向userinfo表中增长10条记录,编号从1-10
create procedure pro6(usname varchar2) is
--定义循环变量,初值为1
v_i number(2):=1;
begin
loop
insert into userinfo values(v_i,usname);
--循环变量自增
v_i:=v_i+1;
--判断是否退出循环
exit when v_i=11;
endloop;
end;
--while
--输入用户名,向userinfo表中增长10条记录,编号从11-20
create procedure pro7(usname varchar2) is
v_i number(2):=11;
begin
while v_i<=20 loop
insert into userinfo values(v_i,usname);
v_i:=v_i+1;
endloop;
end;
--for
--输入用户名,向userinfo表中增长10条记录,编号从21-30
create or replace procedure pro8(usnamevarchar2) is
v_i number(2):=21;
begin
forv_i in 21..30 loop
insert into userinfo values(v_i,usname);
endloop;
end;
----输入用户名,向userinfo表中增长10条记录,编号从40-31
create or replace procedure pro8(usnamevarchar2) is
v_i number(2):=31;
begin
forv_i in reverse 31..40 loop
insert into userinfo values(v_i,usname);
endloop;
end;