Oracle数据库教程

Oracle数据库教程

第一到八章:Oracle数据库的安装及基本语法

第一章习题:总复习
create table RoleSalary(
    id int,
    name varchar(10),
    salary int,
    Title varchar(10),
    sex char(10),
    age int,
    Telephone varchar(11),
    address varchar(20)
);

-- 插入数据
insert all
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (1,'吴邪',4411,'东邪','男','35','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (2,'张起灵',4111,'北哑巴','男','95','13909822112','杭州')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (3,'王胖子',1811,'中胖爷','男','45','13909822112','杭州吴山')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (4,'解雨臣',4331,'西花','男','35','13909822112','杭州山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (5,'黑眼睛',2111,'南瞎','男','85','13909822112','杭州')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (6,'阿宁',5141,null,'女','30','13909822112','杭州')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (7,'云彩',11231,null,'女','25','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (8,'阿贵',11111,'鬼子','男','45','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (9,'霍老太',11211,'霍仙姑','女','85','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (10,'霍秀秀',12311,null,'女','25','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (11,'潘子',11311,'潘爷','男','45','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (12,'陈文静',13311,null,'女','30','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (13,'齐宇',111121,null,'男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (14,'王萌',23311111,'萌哥','男','32','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (15,'谢连环',2311111,'谢九爷','男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (16,'张启山',23231,'佛爷','男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (17,'二月红',32311,'二爷','男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (18,'吴老狗',32211,'狗爷','男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (19,'谢子扬',13111,null,'男','35','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (20,'黑背老六',3211,null,'男','35','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (21,'汪藏海',4111,null,'男','1239','13909822112','长沙')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (22,'黎簇',5111,'小东邪','男','22','13909822112','杭州吴山居')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (24,'金万堂',31111,'堂堂','男','45','13909822112','北京')
into RoleSalary(id, name, salary, Title, sex, age, Telephone, address) VALUES (25,'梁湾',1211,null,'男','30','13909822112','北京')
select 1 from dual;


select name,id,salary,address,sex,age,Title,Telephone
from RoleSalary;
select name
from RoleSalary
where salary>10000;

/*6.第一章:总复习*/
-- 1.查询鬼子大于12000的员工姓名和鬼子
select name,salary
from RoleSalary
where salary>20000;


-- 2.查询id号为18的员工姓名和鬼子
select name,id
from RoleSalary
where id=18;

-- 3.选择工资不在5000到12000的员工的姓名和工资
select name,salary
from RoleSalary
where salary<5000 or salary>12000;

-- 或者
select name,salary
from RoleSalary
where salary not between 5000 and 12000;

-- 4选择地址在杭州的姓名和id
select name,id
from RoleSalary
where address='杭州';


-- 选择id在10到15号的员工姓名和工资
select name,salary
from RoleSalary
where id >10 and id <15;


-- 选择没有别称的员工的姓名和id
select name,id
from RoleSalary
where Title IS NULL;



-- 选择员工姓名第一个名字是吴的员工姓名
select name
from RoleSalary
where name like '吴_';

 								/*第二节:单行函数和多行函数*/
-- SQL语言中不同类型的函数
-- 在select语句中石油字符,数字,日期和转换函数
-- 使用条件表达式

-- 1.单行函数
-- 大小写函数:分别是转换为小写,大写,首字母大写
select lower('ABCdhnf   SSS'),upper('weswedwds'),initcap('sdjsAA sjava')
from DUAL;

-- 字符控制函数
select concat('helloo','word'),substr('hellower',2,3),length('ASDXCV')
from DUAL;
-- 第一个是字符串拼接
-- 第二个是取出字符串
-- 第三个是计算长度

-- 左对齐函数
select lpad(salary,10,'')
from RoleSalary;

-- 数字函数
-- 四舍五入:第二个代表的保留的数位
select round(234.23),round(123.99)
from DUAL;
-- 截断函数
select trunc(345.2,3)
from DUAL;

-- 求余
select mod(1200/2)
from DUAL;

-- 日期函数
select sysdate
from DUAL;

-- 在日期上加上火减去员工数字结果依然是为日期
-- 两个日期相减之差是相差的天数

select sysdate+1,sysdate+10
from DUAL;


--通用函数
-- 这些函数适合如何数据类型,同时爷适用于空值
-- nvl():将空值转换为一个已知的值

-- 例如:求员工的年薪
select name,id,salary*12*(1+nvl(salary,0))
from RoleSalary;

-- 例如:输出name,id ,当别名为null的时候,显示未知
select name,id,nvl(to_char(id),'未知')
from RoleSalary;

-- nvl2函数
-- nvl2(x,y,z):x不为null的时候,返回y,为null返回z
-- 例如:查询别名,为空返回0,不为空返回1
select name ,id,nvl2(Title,0,1)
from RoleSalary;



-- nullif函数
-- nullif(x,y)相等返回null不等返回x
select salary,nullif(id,salary)
from RoleSalary;

-- 重点:条件表达式
-- 在SQL语句中石油case表达式
-- 查询id为10,15,20的员工信息
-- 若id为10,则大于工资的1.1倍
-- 若id为15,则返回工资的1.2倍
-- 若id为20,则返回工资的1.3
select id ,name,

       case id when 10 then salary*1.1
               when 15 then salary*1.2
               when 20 then salary*1.3 end
-- 这个when 10 then salary*1.1读作当id为10,则工资*1.1,以此类推
-- 这个例子就是id为条件,后面为执行
from RoleSalary
where id in(10,15,20);

-- decode函数
-- 例如:
--     查询id为10,15,20的员工信息
-- 若id为10,则大于工资的1.1倍
-- 若id为15,则返回工资的1.2倍
-- 若id为20,则返回工资的1.3

select name,id,decode(id,10,salary*1.1
    15,salary*1.2
    20,salary*1.3
    )
from RoleSalary
where id in(10,20);
-- 第四节:多表查询
create table student(
    id int,
    name varchar(12),
--     技能
    skil varchar(10),
--     部门
    department varchar(10)

);
-- 使用等值和不等值链接在select语句值查询多个表的诗句
-- 使用自链接
-- 使用外连接查询不满足条件的数据

-- 插入表数据
insert all
into student(id, name, skil, department) VALUES (001,'吴邪','黑驴蹄子','九门')
into student(id, name, skil, department) VALUES (002,'张起灵','黑金古刀','九门')
into student(id, name, skil, department) VALUES (003,'王胖子','(炸弹','九门')
into student(id, name, skil, department) VALUES (004,'解雨臣','小刀','九门')
into student(id, name, skil, department) VALUES (005,'黑瞎子','尼泊尔','九门')
into student(id, name, skil, department) VALUES (006,'苏难','刀','汪家人')
into student(id, name, skil, department) VALUES (007,'张启山','枪','九门')
into student(id, name, skil, department) VALUES (008,'黎簇','小刀','九门')
select 1 from DUAL;

select *from student;

select *from RoleSalary;

-- 从两个表值获取数据:语法如下
-- 笛卡尔积错误:省略连接条件,连接条件无效,所有表中的所有行相互连接,为了避免笛卡尔积,可以在where中加入有效的连接条件
select RoleSalary.id,RoleSalary.name,student.id,student.name
from RoleSalary,student
where RoleSalary.id=student.id;
/*避免笛卡尔积错误,使用where来家里两个表的连接*/
/*这个就等值连接
  */

-- 优化:给表起别名
-- 例如;起别名来优化
select r.id,r.name,s.id,s.name
from RoleSalary r,student s
where r.id=s.id;


/*多表情况:连接n个表至少需要n-1个连接条件
  */

-- 非等值连接
select r.id,s.id,r.name,s.name,r.salary,s.skil
from RoleSalary r,student s
where r.salary between r.salary and r.salary;

/*
内连接:合并具有同一列的两个以上的表的行,结果集中不包含一个表与另一个表不匹配的行
外连接
*/
-- 左外连接:在左表这里加油管加号
select r.id,s.id,r.name,s.name,r.salary,s.skil
from RoleSalary r,student s where r.id(+)=s.id;


-- 同理:右外连接
select r.id,s.id,r.name,s.name,r.salary,s.skil
from RoleSalary r,student s where r.id=s.id(+);

-- 内连接:输出表中共同的数据
-- 等值和不等值
-- 外连接:左连接和右连接

-- 自然连接
select id,name,id,skil,salary
from RoleSalary natural join student;
-- join后面跟什么就是使用什么来作为连接输出的数据

-- 方式二:

select id,name,id,skil,salary
from RoleSalary  join student
using (id);
-- 方式三:使用on来作为连接条件
select r.id,r.name,s.id,s.skil,r.salary
from RoleSalary r  join student s
on r.id=s.id
;


/*同理:多个表的情况下也是如此*/

-- 自连接
-- 查询员工吴邪的技能信息
select r.name,s.skil,r.salary
from RoleSalary r ,student s
where r.id=s.id and lower(s.name)='吴邪';

/**/
/*第五节:分组函数*/
-- 分组函数作用于一组数据,并对一组数据返回员工值
-- 组函数:avg,count,max,min,stddev(这个用于标准差),sum
-- 例如:求工资的各种数据
select avg(salary), max(salary),min(salary),sum(salary)
from RoleSalary;

/*在使用组函数的时候,注意数据类型*/

-- count计数函数
select count(id) ,count(name)
from RoleSalary;


-- 工资的方差
select stddev(salary)
from RoleSalary;

-- 统计非空值:这个函数如果统计到不会把空值加入
select count(Title)
from RoleSalary;

-- 返回非空且不重复的记录总数
select count(distinct address)
from RoleSalary;

-- 分组数据
-- 例如:求出各部门的工资
select id,avg(salary)
from RoleSalary
group by id;

-- 使用多个列分组
-- 非法使用组函数
-- 不能在where字句前使用组函数
-- 可以在having后面字句使用组函数
-- 例如:
select avg(salary)
from RoleSalary
-- where avg(salary)>10000 ;
having avg(salary)>12000 ;


-- 组函数嵌套
select max(avg(salary) )
from RoleSalary
group by id;
/**/
/*第六章:子查询*/
-- 背景:谁的工资比张启山高
select salary
from RoleSalary
where name='吴邪';


select name,salary
from RoleSalary
where salary>4411;

-- 使用子查询来优化
select name,salary
from RoleSalary
where salary>(
    select salary
    from RoleSalary
    where name='吴邪'
    ) and salary<(

    select salary
        from RoleSalary
        where name='黎簇'

    );

/*z子查询可以从内到外,也可以从外到内*/

-- 子查询的类型:单行子查询,多行子查询
-- 多行子查询使用的操作符:= > < <= >= 区间
select name,salary
from RoleSalary
where salary>(
    select salary
    from RoleSalary
    where name='吴邪'
) and salary<(

    select salary
    from RoleSalary
    where name='黎簇'
);

-- 返回工资最少的员工的name,id,salary
select name,salary
from RoleSalary
where salary=
    (
        select min(salary)
            from RoleSalary
        );

-- 查询工资大于id为15的员工姓名和工资
select name,salary
from RoleSalary
where salary>(
    select salary
    from RoleSalary
    where id=10
    );
-- 如果内层返回值为空,外循环也不会报错,但是结果为空

-- 多行子查询
-- 操作符:in any all
-- any是任意
-- all是在
-- 例如:
-- 返回id为5的任意工资低的员工的id。salary,name
select id,name,salary
from RoleSalary
where id<>5 and salary (
    select avg(salary)
    from RoleSalary
    );

-- 查询员工在住址在吴山居的员工姓名和工资
select name,salary
from RoleSalary
where address='吴山居';
/*子查询习题*/
-- 1.查询工资最低的员工信息的姓名和工资
select name,salary

from RoleSalary
where salary=(
    select min(salary)
    from RoleSalary
    );
-- 2.查询低于平均工资的姓名工资
select name,salary
from RoleSalary
where salary<(
    select avg(salary)
    from RoleSalary
    );

-- 3.查询那些员工高于平均工资的姓名和工资
select salary,name
from RoleSalary
where salary>(
    select avg(salary)
    from RoleSalary
    );

-- 查询员工在住址在吴山居的员工姓名和工资
select name,salary
from RoleSalary
where address='吴山居';


/*第七章:创建表和管理表*/
/*
常见的数据库对象:表,视图,序列,索引,同义词
*/
-- 查看有那些表的语法:
select *from user_tables;

-- 表的命名规则:必须一字母开通,必须在1-30个字符之间,不能是OrACE保留着

-- 2.创建表:语法如下
-- 第一种方式:(白手起家)
create table emp
(
    id number(10),
    name varchar(5),
    salary number(10,2),
-- 2:代表两位小数
heir_date date
);

--方式2:使用现有的表:原来表的数据爷复制了过来
create table emp2
as
    select id,name,address,Title
from RoleSalary;

select *from emp2;

create table emp3
as
    select id,name,address,Title
from RoleSalary
where id<10;

select *from emp3;

-- 修改表名字:alter table+名字
alter table emp2
add (email varchar(10));
-- 增加了字段

-- 修改字段
alter table student
modify (name number(20,1) default 2000);
-- 这个语句就是把name字段改为number类型

-- 删除字段(列)
alter table emp2
drop column email;

-- 重命名列
alter table emp2
rename column email to sal;

--删除表
drop table emp2;
-- 这个是不可以回滚的
-- 清空表
select *from emp2;

truncate table emp2;
-- 这个语句就是清空所有的表的数据,不可回滚
-- 可以回滚的就是只有增删改

-- 改变表的名称:把emp3表更改为test
rename emp3 to test;

/****************************************************************/
/*习题:创建和管理表
  */
-- 创建表dept
create table dept(
    name varchar(25),
    id number(7)

);

--将员工表中的数据插入dept2中
create table dept2
as
    select *from RoleSalary;

-- 将dept表中的name字段增加到50
alter table dept
modify (name varchar(20));

-- 根据员工表创建新的表
create table R_test
as
    select *from RoleSalary;


-- 删除表dept2
drop table dept2;

-- 在表R_test中增加员工列
alter table dept
add(test_name number(10));


-- 删除表emp2张的name列
alter table dept
drop column name;

 								
create table TEst(
    id int ,
    name varchar(12),
    address varchar(12),
    salary int,
    Title varchar(12),
    department varchar(12)


--         创建了一个表
);

-- 1.使用insert  into语句向表里面插入数据
-- 注意这种语法只能插入一条语句

create table RoleSalary1(
                           id int,
                           name varchar(10),
                           salary int,
                           Title varchar(10),
                           sex char(10),
                           age int,
                           Telephone varchar(11),
                           address varchar(20)
);
-- 插入一条数据
insert into TEst
values (001,'吴邪','吴山居',12000,'东邪','九门');
select *from TEst;


--方式二:指明列字段来插入
insert into TEst(id,name)
values (1,'解雨臣');
select *from TEst;


-- 二:从其它表里面来拷贝数据
-- 例如:
insert into TEst(id,name,salary)
select id,name,salary
from RoleSalary
    where id<20;
-- 注意这个字段必须要一一对应
select *from TEst;


/*三:创建脚本的方式来插入数据*/
/*当前数据库不支持不支持
insert into TEst
    (id,name,salary)
values(&id,'&name',&salary);
*/
--
-- 三:更改数据
-- 使用update语句
-- 保存语句使用commit
update RoleSalary
set salary=3000
where id=1;

select *from RoleSalary;


update RoleSalary
set ADDRESS='北京'
where id=1;


-- 注意:这个语句与where一起结合起来使用,不然会造成数据全部倍更改

-- 更新id为2号的工资和家庭住址,工资和吴邪的一样
update RoleSalary1
set SALARY =(select
    salary from RoleSalary
    where id=8
    )
where id=1;


select *from RoleSalary;



-- 更新中的完整性错误

-- 3.删除表中的数据
-- 使用delete语句删除数据:例如
-- 删除id为1的员工
-- 语法:delete...from..表名
delete from RoleSalary
where id=(
    select name
    from RoleSalary
    where name='吴邪'
    );


/*总结:

  增删改查:
  insert into...
  values(..)


  insert into ...
  select ...from....where...

  改:
  update ...
  set....
  where...

  删:
  delete from...
  where...

  */


create table emp
as
    select id,name,salary,address
from RoleSalary
    where id=1;



/*数据库事务*/
-- 事务:一组逻辑操作单元,使用数据从另一种状态变黄道另一种状态
-- 一个或多个dml语句
-- jdbc技术

-- 事务:commit语句
select *from TEST;

commit ;


-- 回滚:可以恢复到你近期删除一个还原点
rollback ;
						21节:课后练习

-- 1.运行以下脚本
create table my_employee(
    id number(5),
    fist_name varchar(10),
    last_name varchar(10),
    User_id varchar(10),
    salary number(5)
);
-- 显示表的结构
-- desc my_employee;

-- 向表中插入以下数据
insert all
into my_employee values (1,'吴邪','palph','1ratel',896)
into my_employee values (2,'解雨臣','palp','4ratel',886)
into my_employee values (3,'王胖子','alph','3ptel',796)
into my_employee values (1,'张起灵','lph','2patel',8296)
into my_employee values (1,'黑瞎子','paph','1patel',1096)
select 1 from dual;

-- 提交
commit ;

-- 将三号员工的name,修改为王凯旋
update my_employee
set fist_name='王凯旋'
where id=3;

-- 将所有员工的工资少于900的员工修改为1000
update my_employee
set salary = 1000
where salary<900;

-- 检查以下
select *from my_employee;

-- 提交当前的事务
commit ;


-- 删除所有数据
delete from my_employee;

-- 检查所做的修改
select *from my_employee;

-- 清空表
truncate table my_employee;

-- 检查
select *from my_employee;





















































































第九章:约束

/*约束:
  not null
  unique
  primary key
  foreign key
  check

  描述约束,创建和维护约束

  创建和修改约束:
  建表和建表之后

  表级约束和列级约束
  */
-- 1.非空约束
-- 可以在建立表的时候建立
-- not null非空约束
create table emp2(
    id number(10),
--     起名字写法
    name varchar(20) constraint emp_id not null ,
--     默认约束名称写法
    salary number(10,2) not null
);


insert into emp2 values (1,'吴邪',122200.00);


-- unique:唯一约束
create table emp4(
-- 列级约束
    id int,
    name varchar(10) unique ,
    salary varchar(10),
    email varchar(11)
-- 这表里面的姓名是唯一的,不能重复
-- 表级约束
constraint emp4_email_uk unique
);
insert into emp4 values (1,'吴邪','[email protected]');

-- unique可以插入多个空值

-- 主键约束的使用

create table emp5(
--     这个就是主建的创建
    id int primary key ,
    name varchar(10)
);
-- 检验主建

insert into emp5
values (null,'吴邪');
-- 报ORA-01400: 无法将 NULL 插入 ("SYSTEM"."EMP5"."ID") Position: 26

-- 表级主键

/*外键的使用*/
create table emp6(
--     这个就是主建的创建
                     id int primary key ,
                     name varchar(10),
                     department varchar(10) ,
--                      这个就是外键的创建
        constraint emp6_id_fk foreign key (department) references emp6(id)

);

-- 使用级别连空
create table emp5(
--     这个就是主建的创建
                     id int primary key ,
                     name varchar(10)
);


-- chunk约束
-- 又叫检查约束
create table emp8(
    id varchar(12) check ( null ),
    salary number(10,2) check ( salary<20000 )
--     因此这个约束就是用来检查数据的准确性
);

-- 约束2:
-- 添加约束的语法
-- 使用alter table语句
-- 添加或删除约束,但是不能修改约束
-- 有效或无效化约束
-- 添加not null 约束要属于modify语句
-- 例如:

alter table emp5
modify (salary number(10,2) not null );

-- 例如;添加约束
alter table emp2
add constraint emp2_name_uk unique (name);


-- 有效化和无效化
-- 在alter table 语句中使用disable字句将约束无效化
alter table emp2
disable constraint emp2_emial_uk;
-- 这个语句就是使约束无效

-- 查询约束
-- 语法
select constraint_name,constraint_type,
        search_condition
from USER_CONSTRAINTS
where TABLE_NAME='emp1'
-- 这个引号里面的是表名


第十章:视图

-- 第十章:视图
-- 常见的数据库对象:表,视图,序列,索引,同义词
-- 视图:view
-- 任务:描述视图,创建和修改视图的定义,删除视图
-- 从视图中插入查询数据
-- 用过视图插入,修改,删除数据

create table employee(
    id int primary key ,
    name varchar(10) not null ,
    salary number(10,2),
    address varchar(10),
   tele_phone varchar(11),
   QQ_email varchar(12) unique
);



/*视图:视图是一种表,视图是建立在已有的表上,视图依赖以建立的这些表成为基表
  向视图中提供数据内容的语句为select语句,可以将视图连接为存储起来的select语句

  2.视图:可以控制数据访问,简化查询,避免访问相同的数据

  */

insert into employee values (1,'吴邪',12000,'吴山居','15692677113','[email protected]');
-- 创建视图:这个语句就是读作,创建了员工名称为emp_view的视图,视图里面的数据来自employee表下的id,name,salary,
-- 因此这个视图下只能查询到id,name,salary
create view emp_view
as
    select id,name,salary
from employee;

-- 对视图数据进行增删改

update emp_view
set salary=2000
where id=1;

select *from emp_view;


--     对视图数据进行删除
-- 因为有约束限制,所以就不删除
delete from emp_view
where id=1;

-- 对于简化查询


-- 修改视图
create or replace view emp_view3
as
    select name,id,salary,address
from employee;

-- 对视图不想让用户进行增删改
create or replace view emp_view3
as
select name,id,salary,address
from employee;
-- with read only;
-- 这个语句就是限制用户权限,只能阅读

/*2.简单视图和复杂视图
  */


-- 对于简单视图,简单视图是没有分组函数的,而复杂视图有
create or replace view emp_view3
as
select name ,avg(salary) avg_salary ,id
from employee
group by name, id;

select *from emp_view3;


-- 删除视图
drop view emp_view3;


/*top_N分析:
  分析查询员列中最大或最小的n个值
  最大和最小的值的结合是top——N分析所关心的

  */


第十一章:其它数据库对象-索引的使用


/*第十一章:其它数据库对象*/
-- 可供多个用户来产生唯一数值额数据库对象
-- 序列主要以来提供主键值
-- 序列的创建
create sequence empsql
increment by 10  --这个语句就是数值为每次增长10个
start with 10 --从10开始增长
maxvalue 100--提供的最大值
minvalue 100 --提供的最小值
cycle --需要循环
nocycle --不需要循环
nocache --不需要缓存登录




create sequence empsql
    increment by 10  --这个语句就是数值为每次增长10个
    start with 10 --从10开始增长
    maxvalue 100--提供的最大值
    minvalue 10 --提供的最小值
    cycle --需要循环
    nocache ;--不需要缓存登录

select empsql.nextval from DUAL;


create table emp_1
as
select id,name,salary
from employee
where 1=2;


insert into emp_1
-- values (1,'吴邪',2300)
--这里就表可以不手动输入值了,可以使用序列来输入
values (empsql.nextval,'吴邪',2300);


-- 使用这个语句,会自动按照指定的值去增加
select *from emp_1;

-- 2.序列的修改
alter sequence empsql
increment by 1 --每次增长1
nocycle; --不让你循环

-- 注意:序列的初始值只能删除序列或者重建序列来实现


-- 使用序列:序列在以下情况会出现裂缝
-- 回滚,系统异常,多个表同时使用序列就会出现裂缝

/*序列的查看*/
select sequence_name,min_value,max_value,
       increment_by,last_number
from USER_SEQUENCES;

-- 删除序列
drop sequence empsql;

/*2.索引:*/
-- 索引是独立于表的模式对象,可以存储在与表不同的磁盘或表空间中
-- 索引倍删除,或损坏,不会对表产生影响,影响的只是查询的速度
-- 索引一旦建立,数据库管理系统会自动进行维护
-- 在删除员工表时,所有基于改表的所有会自动被删除
-- 通过指针加上数据库服务器的查询速度
-- 通过加快定位数据的非法,减少磁盘的io
-- 1.索引的创建
/*1.自动创建
  在定义主建或唯一索引约束后系统自动在相应的列上创建唯一索引

  2.手动创建:用户在其他列上创建非唯一的索引,以加快查询
  */

-- 创建索引
-- 在英国或多个列上创建索引
create index emp_1_ix
on emp_1(id);
-- 这个就是在表的id字段上建立索引

-- 删除索引:
drop index emp_1_ix;

-- 什么时候改创建索引:
-- 列中数据值分布很广,列经常在where字句或连接条件中出现,表经常被访问而且数据量很大,
-- 访问的数据大概占数据总量的百分之2到百分之4

-- 下列情况下不要创建索引:
-- 表很小,列不经常作为连接条件或出现在where字句。表经常更新

-- 同义词:使用同义词访问相同的对象:syonnym
-- 方便访问其它用户的对象
-- 缩短对象名字的长度


第十二章:控制用户及权限总复习

/*第十二章:控制用户的权限和管理*/
/*创建用户,创建角色,使用grant和revoke语句赋予和回收权限,创建数据库连接*/

-- 权限:数据库安全性:系统安全性,数据安全性
-- 系统权限:对于数据库的权限
-- 对象权限:操作数据库对象的权限
--数据库管理员:dba


-- 创建用户及密码:语法如下
create user root_Test
identified by   root;
/*用户的系统权限:用户创建用户,dba会赋予用户一些系统权限

  创建回话,创建表,创建序列,创建视图,创建过程等权限
  */
-- 语法:
-- 赋予用户权限
grant create session
to root_Test;


-- 创建用户表空间
-- 用户拥有create table权限外还需要分配相应的表空间才可以开辟存储空间用于创建的表

-- 创建用户表空间
-- 这个代表无限制:unlimited
-- -如果要加限制爷可以在后面加上对于的空间内存值
alter user root_Test quota 5m
on USERS;


/*角色:
创建角色并且赋予权限


  */
-- 1.创建角色
create role my_role;

-- 给角色赋予权限:
-- c创建表,创建视图等系统权限
grant create session,create table,create view to my_role;

-- 在执行下一步的工作时候,一定要开辟表空间

-- 2.对象:对象的权限
-- 语法
-- 例如:分配表employee的查询权限
grant select,update
on SYSTEM.EMPLOYEE
to root_Test;
/*这个语句读作授予查询,修改employee表的权限给root_Test用户*/

commit ;

-- 使用户具有分配权限的权利
-- 语法:.........with grant option ;
grant select
on SYSTEM.EMPLOYEE
to root_Test
with grant option ;

-- public关键字:向数据库中所有用户分配权限
-- 语法
grant select,update
on emp_1
to public;
/*这个语句读作:授予查询,修改emp_1的权限,所有用户都有对表的emp_1权限*/


-- 收回权限:
-- revoke
revoke select
on employee
from root_Test;
/*这个语句读作收回root_Test对表employee的查询权限*/

-- 修改用户密码:
alter user root_Test

第十三章:set运算符

-- 第十三章:运算符
-- 描述set操作符
/*
union
intersect
minus
排序:order by

1、并集:union/union all
2.交集:intersect
3.差集:minus

*/
-- 1.union操作符:
select *from EMPLOYEE;


-- 创建员工新的表
create table employee01
as select *from employee
where id=1;

insert all into employee01 values (3,'张起灵',20000,'吴山居','1423323','[email protected]')
select 1 from DUAL;
create table employee02
as select *from employee
where id=1;

-- 求两个表的交集
select id from employee01
union select id from employee02;
-- 答案员工是1,原因是去除重复

-- union的操作描述:上面是一个集合,下面是员工集合,集合中间的是操作符,书写的时候要一一对应

select * from employee01;


select SALARY from employee01
group by SALARY ;
-- 按照工资来排序


-- 取交集:intersect
select id from employee01
intersect
select id from employee02;


-- 差集合:
select id from employee01
minus
select id from employee02;


/*在select列表中的列名和表达式在数量和数据类型上要对于
  括号可以改变执行顺序
  */

select 'study at'
from DUAL
union
select 'I want to'
from DUAL
union select '我的理想'
from DUAL
order by 'stu' desc ;
;

/*习题:*/
-- 1.查询id号,强制不包括工资

select id from employee01
minus
select id from employee02
where id=1;

-- 查询id为3的员工信息,按照工资来排序
select ID,1 from employee01
where id=2
union
select ID,2 from employee01
where id=1
union
select ID,3 from employee01
where id=3
order by 2;

第十四章:高级子查询


/*1.书写多列子查询
  2.在from中使用子查询
  3.在SQL中使用单列子查询
  4.书写相关子查询
  5.使用exists和not exists操作符
  6.使用子查询更新和删除数据
  7.使用with字句

  */

  select *from RoleSalary;

-- 子查询是嵌套在SQL语句中的另一个查询语句
select salary,name from RoleSalary
where salary<(
    select salary
    from RoleSalary
    where id=2
    );
-- 这个语句很明显报错,原因就是单行子查询返回了多个行
-- 多列子查询:
-- 1.查询员工表里面id为3和id为4的住址相同的员工
select name,address,age
from RoleSalary e
where id in (
    select id
    from RoleSalary
    where id in (1,9)


    ) and age in (
        select id
        from RoleSalary
        where id in(1,9)
    )
and id not in (10,18);

-- 使用多列子查询
select name,address,age
from RoleSalary e
where (id,name,age) in (
    select e.id
    from RoleSalary
    where id in(1,10)
    )
and id not in(1,10);


-- 多列子查询:分为两种:承兑比较,不成对比较

-- 在from字句中使用子查询
-- 1.返回员工表中工资大于平均工资的员工的姓名,id,年龄,平均工资
select name,id,age,salary
from RoleSalary e
where salary>(select avg(salary)
    from RoleSalary
    );

-- 在from字句中来实现:
/*
select name,id,age,salary
from RoleSalary e,(select  avg(salary) from RoleSalary) e1
where e.id=e1.id;*/


-- 单列子查询:是一行只返回一列的子查询

select id,name
(case id when (select id from RoleSalary where id=14)then '吴山居'
    else '北京'

    end

    ) location
from RoleSalary;

-- 在order by里面使用子查询
-- 查询员工的姓名,工资,要求按照员工的姓名来排序
select id,name ,salary
from RoleSalary r
order by (select name
    from employee01 e where r.id=e.id
    )asc;

/*相关子查询
  相关子查询按照一行接一行的顺序执行。主查询的每一行都执行一次子查询



  */


--   查询员工表中国字比平均工资高的员工
select name,salary,age
from RoleSalary
where salary>(
    select avg(salary)
    from RoleSalary
    );


-- exists操作符
-- 这个操作符检查在子查询中是否满足条件的行:如果在子查询中存在满足条件的行
-- 不在就在子查询中继续寻找,条件返回TRUE
-- 如果在子查询不存在就返回false

-- 例如:
-- 查询地址在吴山居的姓名,id,住址
select id,name,salary,address
from RoleSalary
where exists(
    select 'A'
    from RoleSalary
    where address='吴山居'
          );

-- not exists操作:不存在
select id
from RoleSalary
where not exists(
    select 'c'
    from RoleSalary
    where id='2'

          );

-- 相关更新
create table emp1
as select *
from RoleSalary;

alter table emp1
add (department_name varchar(10));

-- 更新emp1表
update emp1
set department_name=(
    select department_name
    from EMP1
    where id=emp1.id
    );

-- 相关删除应用举例
-- 例如:删除员工表中,其与emp表皆有的数据
-- 删除两个表里面共有的数据
/*delete from EMP3
where department_id in(
    select department_id
    from EMP3
    where department_id=EMP3.department_id

    )*/
--


-- 七.with字句
/*1.使用with字句,可以避免在select语句中重复书写相同的语句块
  2.with字句将改字句中的语句快执行一次并存储到用户的临时表空间中
  3.使用with字句可以提高查询效率
  */
-- 查询员工的总工资大于平均工资的部门信息

select *from RoleSalary;
with salary as  (
    select salary
    from RoleSalary
    where name='吴邪朱一龙'

)
select id,name
from RoleSalary
where salary>(
    select salary
    from salary
    );



第十五章:PLSQL程序设计

1.plsql是一种高级数据库设计语言,pl/sql中可以使用的SQL语句有:增删改查,撤销,回滚等语句
2.pl/sql程序由三个块组成:声明部分,执行部分,异常处理部分
/*plsql编程*/
/*declare
    *//*这个是谁声明部分*//*

    begin
    *//*执行部分*//*
    exception
*//*执行异常的部分,错误处理*//*

end;*/

-- 1.书写一个helloWord
declare
    --声明的变量,游标等都放在这个位置
    begin
--     程序的执行部分(类似于main方法)
DBMS_OUTPUT.PUT_LINE('hello word!');
/*exception
-- 针对begin中的出现的异常,提供处理的机制
-- when....then..*/
end;

-- 因此最原始的程序就是
declare

    begin
    DBMS_OUTPUT.PUT_LINE('hello Word');
end;


-- 例子:输出员工表的工资信息
declare
--     1.声明变量
    v_sal varchar(20);
    begin
--     这里面的代码块执行的是一个SQL操作
--     2.执行的代码块
    select salary into v_sal from RoleSalary where name='吴邪朱一龙';
-- 输出语句
    DBMS_OUTPUT.PUT_LINE(v_sal);

end;

-- 如果想要输出姓名,地址,邮箱等信息,则多声明结果变量就可以
declare
--     1.声明变量
    v_sal varchar(20);
    v_name varchar(10);
    v_address varchar(10);
begin
    --     这里面的代码块执行的是一个SQL操作
--     2.执行的代码块
    select salary into v_name from RoleSalary where name='吴邪朱一龙';
--     注意:这里的语句书写信息一定要对应
-- 输出语句相当于java里面的输出语句
    DBMS_OUTPUT.PUT_LINE(v_sal);

end;


-- 2.变量类型:与SQL语句的变量一致

-- 3.记录类型:是把逻辑相关的数据作为一个单元存储起来,称作pl/sql pecord 的域,其作用是存放不相同但逻辑相关的信息
-- 定义记录类型语法如下:这个就类似java中的类
-- 例如:
declare
--     1.声明变量
--     声明一定记录类型
    type emp_test  is record(
     v_sal RoleSalary.salary%type,
     v_name RoleSalary.name%type,
     v_address RoleSalary.address%type
        );

--     定义员工记录类型的成员变量
    v_emp_test emp_test;
-- 定义员工记录类型的成员变量

begin
    --     这里面的代码块执行的是一个SQL操作
--     2.执行的代码块
    select salary into v_emp_test from RoleSalary where name='吴邪朱一龙';
    --     注意:这里的语句书写信息一定要对应
-- 输出语句相当于java里面的输出语句
    DBMS_OUTPUT.PUT_LINE(v_emp_test);

end;

2.应用举例

-- 1.plsql的基本语法格式:
-- 2.记录类型(java中的类) type...is record(....);
-- 3.流程控制:1.条件判断。
-- 方式一:if...then..elsif then...else...end if
-- 方式二:case...when...then ..when..then...end;
-- 2.循环结构
-- 方式一:loop...exit when....end loop;
-- 方式二:while...loop...end loop;
-- 方式三:for i in ....loop ...end;

-- goto:与java中的break
-- exit 退出

-- 4.游标的使用:类似于java中的iterator
-- 作用于集合,用于遍历
-- 5.异常处理(三种方式)

-- 6.会书写一个存储函数(有返回值)和存储过程(没有返回值)二者本质一样都是函数
-- 7.会书写一个触发器:


--
declare
--     变量,记录类型的声明
    v_sal int;

    begin
--     程序的执行部分

select salary into v_sal
from RoleSalary where name='吴邪朱一龙';
/*这个语句左杜把查询到的数据赋值给v_sal这个变量里面*/

-- 打印出来
DBMS_OUTPUT.PUT_LINE(v_sal);
-- 下面是异常的处理
end;

declare
--     变量,记录类型的声明
    v_sal int;
    v_name varchar(10);
    v_address varchar(10);
    v_email varchar(10);

begin
    --     程序的执行部分
    select salary ,name,address into v_sal,v_name,v_address
    from RoleSalary where name='吴邪朱一龙';
    /*这个语句左杜把查询到的数据赋值给v_sal这个变量里面*/
-- 打印出来
    DBMS_OUTPUT.PUT_LINE(v_sal);
-- 下面是异常的处理
end;


-- 使用声明记录类型的方式来解决这个问题
declare
    type emp_test is record(
        v_sal int,
    v_name varchar(10),
    v_address varchar(10),
    v_email varchar(10)
                           );
--     变量,记录类型的声明

-- 面向对象的方式来调用
--     声明员工记录类型的变量
    v_emp_record emp_test;
begin
    --     程序的执行部分
    select salary ,name,address into v_emp_record
    from RoleSalary where name='吴邪朱一龙';
    /*这个语句左杜把查询到的数据赋值给v_sal这个变量里面*/
-- 打印出来
    DBMS_OUTPUT.PUT_LINE(v_emp_record.v_address,v_emp_record.v_name);
-- 下面是异常的处理
end;
/*
定义员工变量,其数据类型与已经定义的某个数据变量的类型系统,或者与数据库表的某个列的数据类型系统这个时候可以使用%type,动态的获取数据类型
-- sql中的赋值符号  :=

*/



--流程控制语句
--  p/sql第三章:流程控制语句
-- # 表达式一:
/*if<布尔表达式> then
        SQL语句
end if;
*/

/*方式二:
    if<布尔表达式> then
        SQL语句
else
        其它语句;
end if;*/

--  例子:
-- 查询出员工表中吴邪员工的工资,若工资大于10000则打印salary>1000
declare
    v_sal RoleSalary%rowtype;
    begin
    select salary into v_sal from RoleSalary where name='吴邪朱一龙';
    /*流程控制语句使用:*/
    if v_sal>=2000 then   DBMS_OUTPUT.PUT_LINE('优秀员工!');
    elsif v_sal>8000 then   DBMS_OUTPUT.PUT_LINE('优秀员工最终版!');
    else   DBMS_OUTPUT.PUT_LINE('懒汉员工!');
    end if;
    /*流程控制语句的结束*/
end;


-- case表达式:
/*不建议使用这个方式,限制比较多,有很多的局限性,因此尽量不要使用这个方式*/
declare
    v_sal RoleSalary%rowtype;
    v_temp varchar(10);
begin
    select salary into v_sal from RoleSalary where name='吴邪朱一龙';
    /*流程控制语句使用:*/
   case trunc(v_sal/5000)  when 0  then v_temp:='优秀';
              when 1 then v_temp:='良好';
              when 2 >1000 then v_temp:='合格';
              when 3 >1000 then v_temp:='不及格';
        end case ;

    DBMS_OUTPUT.PUT_LINE('懒汉员工!');

    /*流程控制语句的结束*/
end;

-- 循环语句的使用:
/*循环三要素:初始化条件,循环体,迭代条件*/
-- 例子:使用循环语句输出
-- 1-100
declare
--     1.声明变量来控制循环
    v_i number(5):=1;

    begin
--     2.循环体
    loop
        DBMS_OUTPUT.put_line(v_i);
        exit when v_i>=100;
                v_i:=v_i+1;
    end loop;

end;

-- 2.while循环
declare
    v_i number(5) :=1;
    begin
    while v_i<100 loop
        DBMS_OUTPUT.put_line(v_i);
        v_i:=v_i+1;
        end loop;
end;

-- 3.for循环:
begin
    for c in 1..100 loop
        DBMS_OUTPUT.put_line(c);
        end loop;
end;

-- 例子:输出2到100之间的质数
declare
    v_i number(2):=2;
    v_j number(3) :=2;
    v_flag number(1) :=1;
    begin
    while v_i <=100 loop
        while v_j<=sqrt(v_i) loop
            if v_i mod v_j =0 then v_flag:=0;
                end if;
            v_j=v_j+1;
            end loop;
        v_i:=v_i+1;
        end loop;
end;

第十六章:游标的使用

/*第十六章:游标的使用:*/

-- 在pl/sql程序,对于处理多行记录的事务经常使用游标来实现
-- 游标概念:
-- 1.使用游标大于出吴邪的工资,信息
--     步骤:1.定义游标
    declare
       v_sal RoleSalary%rowtype;
--         1.定义一个游标
        cursor emp_sal_cursor is select salary from RoleSalary where name='吴邪朱一龙';
        begin
--         2.打开游标:
        open emp_sal_cursor;
--         3.提取游标
        fetch emp_sal_cursor into v_sal;
while emp_sal_cursor%found loop
    DBMS_OUTPUT.put_line(v_sal);--输出语句
    end loop;
-- 4.关闭游标
        close emp_sal_cursor;
    end;


/*游标习题*/
-- 利用游标调整员工表里面的员工工资
update RoleSalary
set salary=salary*(1+0.2)
where name='吴邪朱一龙';



select *from RoleSalary
where name='吴邪';

/*
declare
    cursor emp_sal_cursor is select salary,name,id from RoleSalary;
        v_temp number(4,2);--这个变量用于记录调整的基数
    v_empid RoleSalary.id%rowtype;--这个变量原来记录
    v_sal RoleSalary.salary%rowtype;

    begin
-- 开始打开游标
    open emp_sal_cursor;
fetch emp_sal_cursor into v_sal, v_temp,v_empid;
while emp_sal_cursor%found loop
    if v_sal <2000 then v_temp:=0.5;
    else  if v_sal <4000 then v_temp:=0.5;
    else  if v_sal <7000 then v_temp:=0.9;
    else v_temp:=0.6;
    end if;
    update RoleSalary
        set salary=salary*(1+v_temp)
        where id=v_empid;
    fetch emp_sal_cursor into v_empid,v_sal;
    end loop;
close
end;
*/

-- 隐式游标
begin
    update RoleSalary
        set salary=salary+20
    where id=10;

    if sql%notfound then DBMS_OUTPUT.put_line('查无此人');
    end if;
end;

第十七章:异常处理机制


/*40.异常处理*/
/*一个优秀的的程序都应该能够正确处理各种出错的情况,并尽可能的从错误中恢复,因此Oracle提供了异常情况和异常处理来实现错误处理*/
-- 1。预定义异常:数据库预定义的24种异常大约有24个,对这种异常的处理,无需再程序中定义,有Oracle自动将其引发
-- 2.非预定义异常:对于异常情况的处理。需用户在程序中定义,然后有Oracle自动将其引发
-- 3.用户自定义异常:程序执行过程中,出现保存人员认为的非正常情况,对于这种情况的处理,需要用户在程序中定义
-- 例子:
declare
    v_salary RoleSalary%rowtype;
    begin
    select salary into v_salary
    from RoleSalary
        where id=11;
    dbms_output.put_line(v_salary);
-- 定义异常
  /*  exception

   when ...then..*/
exception

    when  too_many_rows then dbms_output.put_line('输出的行数太多了!');
    when others  then dbms_output.put_line('出现其它类型的错误!');
end;


-- 非预定义异常类型
declare
    e_deleteid_exception exception ;
    pragma exception_init ( e_deleteid_exception ,-2292);--这个语句括号里面的序号就是数据库错误编号
    begin

    delete from RoleSalary where id=10;
    exception
    when e_deleteid_exception then dbms_output.put_line('违反了完整性约束,因此不可以删除!!');
end;


-- 用户自定义异常;
declare
--     用户
e_too_heigh_sal exception ;
    v_sal RoleSalary%rowtype;
    begin
    select salary into v_sal from RoleSalary
        where id=10;
    if v_sal>1000 then
        raise  e_too_heigh_sal;
    end if;
    exception
    when e_too_heigh_sal then  dbms_output.put_line('我自定义的员工异常,工资太高了!');
end;


-- 例子:查询员工工资
declare
    v_sal RoleSalary.salary%rowtype;
    begin
    select salary into  v_sal from RoleSalary where id=1000;


    dbms_output.put_line('违反了完整性约束,因此不可以删除!!');
    exception
    when no_data_found then  dbms_output.put_line('查无此人!');
end;


-- 更新员工的工资:如果工资小于200则加100
declare
    v_sal RoleSalary.salary%rowtype;
begin
    select salary into  v_sal from RoleSalary where id=10;
    if v_sal <300 then update RoleSalary set salary=salary+100 where id=10;
  end if;
exception
    when no_data_found then  dbms_output.put_line('查无此人!');
    when too_many_rows then dbms_output.put_line('输出的行数太多!');
end;

-- 更新员工的工资,注意使用用户自定义方式
declare 
--     自定义异常
no_result exception ;
    begin
    update RoleSalary set salary=salary+100 where id=10;
--     使用隐式游标,抛出自定义异常
    if sql %notfound  then
        raise no_result;
    end if;
    exception
--     处理抛出的异常
    when no_result then
        dbms_output.put_line('更新失败!');
end;

第十八章:存储过程和存储函数

/*存储过程和存储函数*/
-- 程序存储在数据库,并可以在如何地方来运行他,这种就叫做存储过程和存储函数。过程和函数统称SQL子程序,他们是被命名的SQL块,均存在数据库中
-- 创建函数:语法如下
/*
create or replace function func_name(id number,name varchar(10),salary number)--括号里面的是参数,参数类型
return number--函数的返回值
is
--         1.函数使用过程中,需要声明的变量,记录类型,游标

begin
--     2.函数的执行体

exception
-- 3.处理函数执行中的异常

end;

*/

-- 例如:使用函数输出helloWord
create or replace function hello_func

return varchar2
is
begin
   return 'hellWord';
end;

--     调用函数
begin
    dbms_output.put_line(hello_func());
end;

-- 有参数的函数
create or replace function hello_func(v_logo varchar(10))

    return varchar
    is
begin
    return 'hell'||v_logo;
end;

begin
    dbms_output.put_line('人家是函数!');

end;


-- 例子:创建员工存储函数,返回当前的系统时间
create or replace function qet_sysdate
return date
is
    v_date date;
        begin
            v_date :=sysdate;
            return v_date;
        end;
--     调用函数
select qet_sysdate() from DUAL;

-- 例子:定义带参数的函数,两个数相加
create or replace function add_paraw(v_num1 number,v_num2 number)
return number
is
v_sum number(10);
    begin
        v_sum=v_num1+v_num2;
        return v_sum;
    end;
begin
    dbms_output.put_line(add_paraw(1,3));
end;

--     定义员工函数,获取给定部门工资总和,要求:部门号定义为参数,工号总和定义为返回值
create or replace function get_sal(dept_id number)
return number
is
v_sumsal number(10);
    cursor salary_cursor is select *from RoleSalary where id=10;

    begin
        for c in salary_cursor loop
            v_sumsal:=v_sumsal+100;
            end loop;
        return v_sumsal;
    end;

/*关于out参数:因为函数只能有员工返回值,pl/sql程序可以通过out参数实现多个返回值*/


create or replace function get_sal_test(dept_id number,total_sal  out number)
    return number
    is
    v_sumsal number(10);
    cursor salary_cursor is select *from RoleSalary where id=10;

begin
    for c in salary_cursor loop
            v_sumsal:=v_sumsal+100;
        end loop;
    return v_sumsal;
end;

二:存储过程

--     存储过程定义语法与函数相似,只不过没有返回值:定义员工存储过程获取给定部门的工资总和
create or replace procedure get_sal(dept_id number,sun_sal number)
is
cursor salary_cursor is select salary from RoleSalary where id=10;
    begin
        sun_sal:=0;
        for c in salary_cursor loop
            sun_sal:=sun_sal+100;
            end loop;
        dbms_output.put_line(sun_sal);
    end;

第十九章:触发器

/*触发器:*/

-- 触发器和许多关系型数据库系统都提供的一项技术,在Oracle系统里,触发器类似过程和函数,都有声明,执行和异常处理过程的pl/sql块
-- 触发器类型;触发器在数据库里独立的对象存储,他与存储不同的是,存储过程通过其它程序来启动运行或直接启动运行。而触发器是由一个事件来启动运行
-- 及触发器是当某个时间自动隐藏,并且触发器不直接接收参数


-- 1.dml触发器:Oracle可以在dml语句进行触发,可以在DML操作前或后操后进行触发,并且可以对每个行或者列上进行触发
-- 2.替代触发器
-- 3.系统触发器

/*触发事件:插入,删除,更改*/

-- 创建触发器的语法:
create or replace trigger update_emp_trigger
    after
--         insert
--     update  这几个操作,可以引起触发器
    update on RoleSalary
    for each row
    begin
        /*这里是触发器要执行的语句*/
        DBMS_OUTPUT.PUT_LINE('你好,我是触发器!');
    end;
-- 声明了触发器后,对表进行更新,删除,插入就发触发这个语句

你可能感兴趣的:(数据库,oracle,sql)