om ? PhoneNum ?
right join ?PhoneType on PhoneNum.pTypeId=PhoneType.ptId
--full join :可以得到左右连接的综合结果--去重复
select PhoneNum.*,PhoneType.*
from ? PhoneNum ?
full join ?PhoneType on PhoneNum.pTypeId=PhoneType.ptId
?
17.事务
?
一种处理机制。以事务处理的操作,要么都能成功执行,要么都不执行
?
事务的四个特点 ACID:
A:原子性:事务必须是原子工作单元;对于其数据修改,要么全都执行,要么全都不执行。它是一个整体,不能再拆分
C:一致性:事务在完成时,必须使所有的数据都保持一致状态。。某种程度的一致
I:隔离性:事务中隔离,每一个事务是单独的请求将单独的处理,与其它事务没有关系,互不影响
D:持久性:如果事务一旦提交,就对数据的修改永久保留
?
使用事务:
将你需要操作的sql命令包含在事务中
1.在事务的开启和事务的提交之间
2.在事务的开启和事务的回滚之间
三个关键语句:
开启事务:begin transaction
提交事务:commit transaction
回滚事务:rollback transaction
?
?
declare @num int =0 --记录操作过程中可能出现的错误号
begin transaction
? update bank set cmoney=cmoney-500 where name='aa'
? set @num=@num+@@ERROR
? --说明这一句的执行有错误 ?但是不能在语句执行的过程中进行提交或者回滚
? --语句块是一个整体,如果其中一句进行了提交或者回滚,那么后面的语句就不再属于当前事务,
? --事务不能控制后面的语句的执行
? update bank set cmoney=cmoney+500 where name='bb'
? set @num=@num+@@ERROR
? select * from bank
? ?if(@num<>0 ) ?--这个@@ERROR只能得到最近一一条sql语句的错误号
? ? ?begin?
? ? ?print '操作过程中有错误,操作将回滚'?
? ? ?rollback transaction
? ? end?
? ?else?
? ? ?begin ?
? ? ?print '操作成功'?
? ? ?commit transaction ?
? ? end?
? ??
? ? --事务一旦开启,就必须提交或者回滚
? ? --事务如果有提交或者回滚,必须保证它已经开启
?
?
18.视图
?
视图就是一张虚拟表,可以像使用子查询做为结果集一样使用视图
select * from vw_getinfo
使用代码创建视图
语法:
create view vw_自定义名称
as
查询命令
go
?
?
--查询所有学员信息
if exists(select * from sysobjects where name='vw_getAllStuInfo')
?drop view vw_getAllStuInfo
go --上一个批处理结果的标记
create view vw_getAllStuInfo
as
--可以通过聚合函数获取所以记录数
?select top (select COUNT(*) from Student) Student.StudentNo,Student.StudentName,grade.ClassId,grade.classname from Student
inner join grade on Student.ClassId=grade.ClassId ?order by StudentName --视图中不能使用order by
--select * from grade --只能创建一个查询语句
--delete from grade where ClassId>100 --在视图中不能包含增加删除修改
go
?
--使用视图。。就像使用表一样
select * from vw_getAllStuInfo?
--对视图进行增加删除和修改操作--可以对视图进行增加删除和修改操作,只是建议不要这么做:所发可以看到:如果操作针对单个表就可以成功,但是如果 多张的数据就会报错:不可更新,因为修改会影响多个基表。
update vw_getAllStuInfo set classname='asdas' ,studentname='aa' where studentno=1
?
?
19.触发器
?
触发器:执行一个可以改变表数据的操作(增加删除和修改),会自动触发另外一系列(类似于存储过程中的模块)的操作。
语法:
create trigger tr_表名_操作名称
on 表名 after|instead of 操作名称
as
go
if exists(select * from sysobjects where name='tr_grade_insert')
drop trigger tr_grade_insert
go
create trigger tr_grade_insert
on grade for insert ---为grade表创建名称为tr_grade_insert的触发器,在执行insert操作之后触发
as
declare @cnt int
set @cnt = (select count(*) from student)
select * ,@cnt from student
select * from grade
go
--触发器不是被调用的,而是被某一个操作触 发的,意味着执行某一个操作就会自动触发 触发器
insert into grade values('fasdfdssa')
---替换触 发器:本来需要执行某一个操作,结果不做了,使用触 发器中的代码语句块进行替代
if exists(select * from sysobjects where name='tr_grade_insert')
drop trigger tr_grade_insert
go
create trigger tr_grade_insert
on grade instead of insert ---为grade表创建名称为tr_grade_insert的触发器,在执行insert操作之后触发
as
declare @cnt int
set @cnt = (select count(*) from student)
select * ,@cnt from student
select * from grade
go
insert into grade values('aaaaaaaaaaaa')
go
---触 发器的两个临时表:
--inserted: 操作之后的新表:所有新表与原始的物理表没有关系,只与当前操作的数据有