1、概述
触发器是由事件来触发某个操作,这些事件包括insert、update、delete事件。所谓事件就是指用户的动作或者触发某项行为。如果定义了触发程序,当数据库执行这些语句的时候,就相当于事件发生了,就会自动激发触发器执行相应的操作。
2、触发器的创建
2.1、创建语法
create[or replase]trigger 触发器名称
{before|after} {insert|update|delete} on 表名
for each row
触发器执行的语句块;2.2、举例1
先创建两张表备用
createtable test_trigger(
id intprimarykeyauto_increment,
t_note varchar(30));createtable test_trigger_log(
id intprimarykeyauto_increment,
t_log varchar(30));
创建触发器:在向test_trigger数据表中插入数据之前,向test_trigger_log数据表中插入before_insert的日志信息
delimiter//createtrigger before_insert
before inserton test_trigger
for each rowbegininsertinto test_trigger_log (t_log)values('before insert');end//delimiter;
向test_trigger数据表中插入数据
insertinto test_trigger(t_note)values('测试');
查看test_trigger_log数据表中的日志信息
select*from test_trigger_log;2.2、举例2
创建触发器:在向test_trigger数据表插入数据之后,向test_trigger_log数据表中插入after_insert的日志信息
delimiter//createtrigger after_insert
afterinserton test_trigger
for each rowbegininsertinto test_trigger_log(t_log)values('after_insert');end//delimiter;2.3、举例3createtrigger salary_check_trigger
before inserton employees
for each rowbegindeclare mgsalary double;select salary intoend
二、存储过程
1、创建语法
delimiter//create[orreplace]procedure 过程名(
参数1[in|out|inout] 数据类型,
参数2[in|out|inout] 数据类型,
……
)is/as
声明变量
begin
语句块;
end//delimiter;
例子:
创建一张表
createtableuser(
id number(10)primarykey,
name varchar(100));
使用存储过程向user数据表插入数据
delimiter//createorreplaceprocedure"insertuser"(
id in number,
name in varchar2
)isbegininsertintouservalues(id,name);end//delimiter;
调用存储过程:
如果是命令窗口就用 [exec 存储过程名]
如果是sql窗口就用 [begin 存储过程名 end]
如果是程序中调用就用 [call 存储过程名]2、定义一个指向select的存储过程
createorreplaceprocedure pro_name
as--定义一个游标,并且为其指定作用CURSOR cur_name isselect*from tbl_name;--定义游标类型
cur_type cur_name%rowtype;beginfor cur_type in cur_name
loop--当循环到游标内容为空时退出循环exitwhen cur_name%notfount;--打印
dbms_output.put_line('姓名:'||cur_type.name||','||'学号:'||cur_type.id);--关闭循环endloop;end;
1、关系运算
= 等号
!= 不等号
< <= 小于 小于等于
> >= 大于 大于等于
between...and...
in(值1,值2...)等同于 过滤的对象 = 值1 or 过滤的对象 = 值2 or ...
distinct 去重
2、集合运算
intersect 交集
union 并集,去重
union all 并集,不去重
minus 补集
3、算数运算
+ - * /
4、数据类型间的相互转换
4.1、转换日期型
to_date(x,y) y的长度要和x保持一致
如:to_date(sysdate,'yyyy-mm-dd hh24:mi:ss')
4.2、转换字符型
to_char()
4.3、转换数字型
to_number()
5、特殊字符查询运算
is null
is not null
like '_'表示具体的一个位,'%'表示不确定的位数
五、查询
1、查询格式
select 要返回的信息
from 表
join...on...
where 过滤条件
group by 分组字段
having 分组后的过滤条件
order by 排序字段
2、运行顺序
from
where
group by
having
select
order by
在oracle中没有mysql中的limit,当我们需要找某列的最大值或最小值时,需要借助函数实现
select * from (
select * from student
order by id
)
where rownum <= 2;
3、子查询
3.1、子查询使用场景、条件:
当条件不明确时,使用子查询查出具体的值,再进行过滤
当我们需要的条件不满足时,通过子查询构造出我们需要的结果集再进行查询
3.2、子查询的返回值:
子查询返回单行结果,一个值用等号进行过滤
子查询返回多行结果集,多个值用in进行过滤
子查询返回多行多列结果集,用in进行过滤
优先将查询结果的数据返回过滤到最小,然后再对结果集进行关联查询
4、连接查询
4.1、格式
[inner] join...on... 内连接
left [outer] join...on... 左外连接
right [outer] join...on... 右外连接
full [outer] join...on... 全连接
左/右外连接的结果集是显示查询的主表的所有数据,以及从表跟主表相交的部分,从表不足的部分(行)补NULL
全连接的结果集是两个表相交的部分正常显示,不同的部分互补NULL
4.2、oracle独有写法
内连接
select ...
from 表1,表2,...
where 关联条件1/过滤条件 [and/or 关联条件2 and/or ...]
左外连接
select ...
from 表1,表2,...
where 表1的某个字段 运算符 表2的某个字段(+) 表1是主表,表2是从表
右外连接
select ...
from 表1,表2,...
where 表1的某个字段(+) 运算符 表2的某个字段 表2是主表,表1是从表
5、伪列(oracle独有)
rownum 对某列进行排序,可以使用它来限制查询返回的行数
rowid 返回当前列的ID值
删除重复行的rowid写法
delete from grade t2
where rowid != (
select max(rowid)
from grade t
where t.name = '张三'
and t.subject = 'Chinese'
)
and t2.name = '张三'
and t2.subject = 'Chinese';
commit;
六、操作
1、数据插入
insert into 表名(列名1,列名2,...)
values(值1,值2,...);
列名可以省略,当省略列名时,默认是表中的所有列名,列名顺序为表定义中列的先后顺序
值的数量和顺序要与列名的数量和顺序一致,值的类型与列名的类型一致
2、向表中插入一个结果集
insert into 表名(列名1,列名2,...)
查询结果集;
在这种语法下,要求结果集中的每一列的数据类型必须与表中的每一列的数据类型一致,且数量也一致
3、数据更新
update 表名 set 列名1=值,列名2=值,...where 条件;
没有where条件的话是全表更新
4、数据删除
delete from 表名 where 条件;
truncate table 表名;
truncate是将表中的数据全部删除(清空数据)
七、建表
1、建表语法
create table 表名();
2、表的约束
primary key 主键约束
foreign key 外键约束
check 检查约束
unique 唯一约束
not null 非空约束
alter table 表名 add constraint 约束名 约束内容;
alter table 表名 add constraint
primary key(列名1,列名2,...); 添加主键约束
alter table 表名 add constraint
foreign key(列名1,列名2,...)
references 从表名(列名1,列名2,...); 添加外键约束
alter table 表名 add constraint check(条件); 添加check约束
alter table 表名 add constraint unique(列名); 添加唯一约束
alter table 表名 modify 列名 not null; 添加非空约束
alter table 表名 drop constraint 约束名; 删除约束
3、对表的操作
3.1、创建表
create table 表名(
列名1 类型,
列名2 类型,
...
);
3.2、复制表结构
create table 表名1
as select * from 表名2 where 1=2;
3.3、复制表结构和表中数据
create table 表名1
as select * from 表名2 where ...;
3.4、删除表
drop table 表名;
3.5、添加列
alter table 表名 add 列名 类型;
3.6、修改列类型
alter table 表名 modify 列名 类型;
3.7、修改列名
alter table 表名 rename column 旧列名 to 新列名;
3.8、删除列
alter table 表名 drop column 列名;
3.9、修改表名
alter table 表名 rename to 新表名;
3.10、给表添加注释
comment on table 表名 is 注释;
3.11、对列添加注释
comment on column 表名.列名 is 注释;
3.12、创建索引
create [unique] index 索引名 on 表名(列名1,列名2,...);
3.13、删除索引
drop index 索引名;
3.14、创建序列
create sequence 序列名
[start with num] 从哪开始
[increment by increment] 每次增加多少
[maxvalue num | nomaxvalue] 最大值
[minvalue num | nominvalue] 最小值
[cycle | nocycle] 是否循环
[cache num | no cache]; 在内存中保留多个序号
3.15、删除序列,序列不能更改,只能删除重建
drop sequence 序列名;
3.16、创建视图
create or replace[{force | noforce}] view 视图名
as
select 查询
[with read only constraint] 表示视图只读,不加则表示视图可以进行增删改
force:即使基表不存在,也可以创建该视图,但是该视图不能正常使用,当基表创建成功后,视图才能正常使用
noforce:如果基表不存在,无法创建视图,默认选项
3.17、删除视图
drop view 视图名;
4、对用户的操作
4.1、创建用户
create user 用户名 identifed by password [account lock | unlock]
4.2、给用户授权
grant connect, resource to 用户名;
直接将connect角色、resource角色授予用户
connect角色:连接数据库;resource:正常使用数据库
例如:
(1)给用户创建表的权限
grant create table to 用户;
(2)给用户创建视图的权限
grant create view to 用户;
4.3、收回用户权限
revoke 角色|权限 from 用户(角色)
4.4、修改用户密码
alter user 用户名 identified by 新密码;
4.5、给用户加锁/解锁
alter user 用户名 account lock|unlock;
5、DBlink
5.1、创建DBlink
create [public] database link dblink名
connect to 数据库用户名 identified by "数据库密码";
using 'TNS连接串信息';
--TNS连接串信息:可以使用整串信息,也可以使用代表这串信息的别名
5.2、查看用户是否具备创建dblink的权限
select * from user_sys_privs where privilege like upper('%DATABASE LIKE%') and username='用户名';
5.3、授权用户创建dblink的权限
grant
create public database LINK,
drop public database LINK
to 用户名;
5.4、给dblink创建同义词
create synonym 同义词名 for dblink连接的数据库里的对象@dblink名;
如:create synonym TEST for company@TESTLINK;
--company:数据库里的一张表
--TESTLINK:创建的连接到数据库的dblink表
6、创建同义词
create [or replace] [PUBLIC] synonym 同义词名 for 用户名.对象名;
--对象包括:表、视图、序列、过程、函数、程序包等
--默认情况下创建私有同义词,只能被当前创建用户使用
如:create or replace public synonym emp for scott.emp;
创建公有同义词,这样的话其他用户直接访问emp就是访问了scott用户下的emp表了
7、删除同义词
drop synonym 同义词名;
8、给用户授权 创建/删除 同义词
grant
create public synonym,
drop public synonym
to scott;
1、声明变量
declare
变量 数据类型 := 初始值;
变量 数据类型 := &提示字段; 自定义输入数据
变量 表名.列名%type := 初始值; 将整个表的数据拿到自身,需要使用其中的数据类型时,表名.列名调用即可
begin
select...sql取数
into...对应变量
dbms_output.put_line(); 数据输出格式
end;
2、条件判断
2.1、if...else...
declare
声明变量
begin
逻辑操作
select...
if 条件1 and/or 条件2 then
操作1;
elsif 条件3 and/or 条件4 then
操作2;
...
else
其他操作;
end if;
end;
2.2、case...when...
declare
声明变量
begin
逻辑操作
case
when 条件1 and/or 条件2 then
操作1;
when 条件3 and/or 条件4 then
操作2;
...
else
其他操作;
end case;
end;
3、循环控制
3.1、loop
declare
声明变量
begin
逻辑操作
loop
循环体
if 退出循环的条件 then
exit;
end if;
--退出循环的简写
exit when 退出循环的条件;
end loop;
end;
3.2、while
declare
声明变量
begin
while 进入循环的条件 loop
循环体
end loop;
end;
3.3、for
declare
声明变量
begin
逻辑操作
for 循环变量 in 循环下限 .. 循环上限 loop
循环体
end loop;
end;
4、游标
游标就是一个指向结果集的指针,通过这个指针,可以获取到指向的结果集中的数据
4.1、显示游标
declare
声明变量
cursor 游标名 is
select 查询结果集;
begin
--使用显示游标结合循环,依次获取到游标指向的结果集的每一行
for 循环变量 in 游标名 loop
循环体
在循环体内可以依次使用结果集的每一行数据,使用方式就是:循环变量.游标指向的结果集的列名
end loop;
end;
开发规范:游标名以c_开头
4.2、参数游标
declare
声明/定义游标
cursor 游标名(参数1 数据类型,参数2 数据类型,...) is
select 查询结果集;
begin
--使用游标
for 循环变量 in 游标名(具体的值1,具体的值2,...) loop
循环体
end loop;
end;
开发规范:参数名以p_开头
4.3、手动管理游标
declare
声明游标
cursor 游标名(参数1 数据类型,参数2 数据类型,...) is
select 查询结果集;
--需要定义个游标变量
变量名 游标名%rowtype;
begin
--使用游标
open 游标名(实际的值1,实际的值2,...); --打开游标
loop
--提取数据:将获取到的数据分别赋值给变量
fetch 游标名
into 游标变量
--退出循环
if 游标名%notfound then
exit;
end if;
--退出循环可以简写成
exit when 游标名%notfound;
数据操作(增删改查)
close 游标名; --关闭游标
end;
十、自定义函数
create or replace function 函数名(
参数1 [in|out|in out] 数据类型,
参数2 [in|out|in out] 数据类型,
...
)
return 返回结果的数据类型
is/as
begin
自定义函数的计算逻辑
return 计算结果; --函数的执行体中一定要包含返回值
end;
十一、package
1、创建包头
create [or replace] package 包名
is/as
--存储过程
procedure 过程名1;
procedure 过程名2(参数名 参数类型 数据类型);
--函数
function 函数名1 return 计算结果的数据类型;
function 函数名2(参数名 参数类型 数据类型) return 计算结果的数据类型;
end 包名;
2、创建包体
create [or replace] package body 包名
is/as
--过程
procedure 过程名
is
过程的完整代码
end 过程名;
--函数
function 函数名
return 计算结果的数据类型
is
函数的完整代码
end 函数名;
end 包名;
十二、SQL复制表结构及其数据
1、只复制表结构
1.1、create table a
as
select * from b
where 1=2;
1.2、create table a
like
b;
2、复制表结构及其数据
create table a
as
select * from b
3、只复制数据
3.1、如果两个表结构一样
insert into a
select * from b
3.2、如果两个表结构不一样
insert into a(column1,column2...)
select column1,column2,...
from b
2、行转列
首先现将行数据转换为一个map的key-value键值对,然后使用炸裂函数
SELECT name, subjects, score
FROM(SELECT name, MAP('语文',chinese,'数学',math,'英语',english) s
FROM score_stu1) a
LATERAL view explode(a.s) t AS subjects, score