一、变量的定义与赋值
declare @变量名 类型 set @变量名=值 eg、 --查汽车表中名称含有宝马两个字的 declare @name varchar(20) set @name='宝马' select * from car where Name like '%'+@name+'%' -- 查汽车表中所有汽车的平均值并输出 declare @price decimal(10,4) select @price = AVG(Price) from Car print '所有汽车的平均价格为:'+cast(@price as varchar(20))
二、语句
1、输出语句 print '字符串'
2、分支语句
a、if else
1 if 判断条件 2 begin 3 要执行的语句 4 end 5 else 6 begin 7 要执行的语句 8 end
b、case 语句(相当于C#的swtich case)(两种用法)
1.简单Case函数
CASE sex WHEN '1' THEN '男' WHEN '2' THEN '女' ELSE '其他' END
2.Case搜索函数
CASE WHEN sex = '1' THEN '男' WHEN sex = '2' THEN '女' ELSE '其他' END
eg1、
1 declare @ccname varchar(20) 2 set @ccname = '宝马' 3 select * from Car where Name like 4 case 5 when @ccname='宝马' then '%宝马%' 6 when @ccname='奥迪' then '%奥迪%' 7 else '%' 8 end
1).两者相比,Case搜索函数功能更强。
2).Case函数类似于if……else if 语句,只返回第一个符合条件的值,之后的部分会被忽略
注意:语句结束之后不要写分号或逗号
三、存储过程
1、不带参数的存储过程(跟 视图作用相同)
eg
1 create procedure MyPRO --procedure为创建存储过程关键字,也可以简写proc,MyPRO为存储过程名
2 as
3 select * from authors
4 --执行存储过程
5 exec mypro --exec表示执行存储过程
2、带参数的存储过程
1 create procedure BuyFriut
2 @Uid varchar(50),
3 @Fcode varchar(50),
4 @Sl int
5 as
6 begin
7 declare @kc int,@price float
8 select @kc=Numbers,@price=Price from Fruit where Ids=@Fcode
9 if @Sl>@kc
10 begin
11 print '库存不足!'
12 end
13 else
14 begin
15 declare @ye float
16 select @ye=Account from Login where UserName=@Uid
17 if @ye>= @price*@Sl
18 begin
19 update Fruit set Numbers=Numbers-@Sl where Ids=@Fcode
20 update Login set Account=Account-@price*@Sl where UserName=@Uid
21 declare @sj int
22 set @sj = cast(rand()*10000 as int)
23 insert into Orders values(@sj,@Uid,GETDATE())--添加内容的时候 先写主键表,再写外键表
24 insert into OrderDetails values(@sj,@Fcode,@Sl)
25 end
26 else
27 begin
28 print '余额不足!'
29
30 end
31 end
32 end
33
34 go
35 --使用存储过程
36 declare @s int
37 exec @s = BuyFriut 'wangwu','k001',20
38 print @s
39
40 --删除存储过程
41 drop proc BuyFriut
3、触发器
触发器是一种特殊的存储过程,只有当试图用数据操作语言DML来修改数据时才会触发,DML包含对视图和表的增、删、改。
触发器分为DML触发器和DDL触发器,其中DML触发器会对数据表,视图进行insert、update、delete的时候触发。DDL则是create、alter、drop等时触发。
DML触发器又分为after(之后触发)和insert of(之前触发)触发器。
如果在创建触发器的时候不指定类型,则默认是after触发器。
触发器有两个虚拟的临时表:插入表(inserted)和删除表(deleted),由系统在内存中创建,不会保存到数据库。并且两张表都是只读的。当触发器完成工作后,这两张表会自动删除。
增加:inserted表 记录
删除:deleted表 记录
修改:inserted表记录修改前 deleted表记录修改后
修改数据时现删掉该记录,然后再增加一天新的记录。这样inserted和updated就都存在记录了。
触发器本身就是一个事务,可以利用事务的回滚,撤销操作。事务就是要么都执行,要么一条都不执行。
创建触发器
语法:
1 create trigger [shema_name . ] trg_name 2 on { table | view } 3 [ with encryption ] 4 { for | after | instead of } 5 { insert , update , delete } 6 as 7 sql_statement
a、创建insert触发器
1 if(object_id('tgr_test_insert','tr') is not null) 2 drop trigger tgr_test_insert --删除触发器 3 go 4 create trigger tgr_test_insert 5 on student --创建在student表 6 for insert --insert触发 7 as 8 declare @id int,@name varchar(20),@sex char(2),@age int 9 --查询inserted表中已经插入的信息 10 select @id = id,@name = name,@sex = sex, @age = age from inserted 11 --用查到的信息加入到会员表中 12 if(@age >30) --如果年龄不符合 则修改 13 begin 14 update student set age = 30 where id = @id 15 print '年龄太大,已自动修改为30' 16 end 17 insert into [user] (userName,passWord,RoleId) values (@name,@sex + cast(@age as varchar),3) 18 print '添加学生成功!'; 19 print '添加会员成功!'
对student表创建触发器后对该表执行insert后
insert into student (name,sex,age,mail) values ('海盗船长','男',88,'853020304@qq.com')
b、创建update触发器
1 if(object_id('tgr_student_update','tr') is not null) 2 drop trigger tgr_student_update 3 go 4 create trigger tgr_student_update 5 on student 6 for update 7 as 8 declare @oldName varchar(10),@newName varchar(10) 9 select @oldName = name from deleted; --查找更新前的数据 10 select @newName = name from inserted;--查找更新后的数据 11 if(@oldName = @newName) 12 begin 13 print '数据相同' 14 rollback tran; --回滚 不执行修改操作 15 end 16 else 17 print '修改成功'
update student set name='海盗船长'
事务在触发器中结束。批处理已中止。
update student set name='粉红娘娘'
修改成功。
c、创建delete触发器
eg
select * from Loginone
select * from biandong
go
--创建触发器
create trigger TR_LOGINONE_DELETE
on Loginone
a、for delete 触发器 --删除的时候执行(第一类)
eg1、
1 create trigger TR_STUDENT_DELETE 2 on Student 3 as 4 begin 5 declare @uid varchar(50),@name varchar(50) 6 select @uid=UserName,@name=Name from deleted 7 insert into biandong values(@uid,@name,'删除') 8 end 9 10 go 11 --在对表loginnoe进行删除的时候触发器执行 12 delete from Loginone where UserName='aaa' 13 14 go
eg2、
if(object_id('tgr_student_delete','tr')is not null) drop trigger tgr_student_delete go create trigger tgr_student_delete on student for delete as if(exists(select * from sys.databases where name = 'studentBackup')) insert into studentBackup select name,sex,age,mail from deleted; else print '不存在,创建再插入' create table studentBackup ( name varchar(20), sex char(2), age int, mail varchar(20) ) insert into studentBackup select name,sex,age,mail from deleted;
delete from student select * from student select * from studentBackup
b、instead of delete 触发器 --替代执行(第三类)
eg1、
1 --删除student里面的数据的时候用另外两条语句替代,先删从表再删主表 2 3 create trigger TR_STUDENT_DELETE 4 on Student 5 instead of delete 6 as 7 begin 8 declare @sno varchar(20) 9 select @sno=sno from deleted 10 delete from score where sno=@sno 11 delete from student where sno=@sno 12 end 13 --执行删除的时候触发 14 delete from student
eg2、
if(object_id('tgr_student_inteadof','tr') is not null) drop trigger tgr_student_inteadof go create trigger tgr_student_inteadof on student instead of delete -- update , insert as declare @id int,@name varchar(20) select @id = id,@name = name from deleted; --instead of 先触发 --先删除user表信息 delete from [user] where userName = @name; --再删除student表信息 delete from [student] where id = @id; delete from student where name = '海盗船长'
修改触发器
alter trigger tgr_test_insert on student for insert as print 'ok'
禁用触发器
disable trigger tgr_test_insert on student
启用触发器
enable trigger tgr_test_insert on student
查询已创建的触发器
select * from sys.triggers
c、after delete --删除之后执行(第二类)
4、事务
a、开始事务 begin tran(transaction)
b、提交 commit
c、回滚 rollback
eg
select * from Car select * from Brand begin transaction --开始事务 delete from Car where Code='c005' delete from Brand where Brand_Code='b002' if @@ERROR=0--判断是否出错,如果执行没错@@ERROR为0 begin commit -- 提交事务 end else begin rollback--回滚事务 end --try catch begin transaction --开始事务 begin try --try里面写要执行的代码 delete from Car where Code='c005' delete from Brand where Brand_Code='b002' commit end try begin catch rollback end catch
四、视图与存储过程的区别
视图:
视图由SELECT查询语句所定义的一个虚拟表,是查看数据的一种非常有效的方式,同真实的数据表一样,视图也包含一系列带有名称的数据列和数据行,但视图与数据表又有很大的不同,视图中的数据并不真实的存在于数据库中。视图返回的是结果集。
存储过程:
存储过程(Stored Procedure)是数据库系统中封装的代码模块,是一组为了完成特定功能的SQL语句集,经编译后存放在数据库服务器中,用户通过指定存储过程的名字并给出参数(如果该存储过程带有参数)来执行它。具有很好的可重用性。可以创建一个过程供永久使用,或在一个会话中临时使用(局部临时过程),或在所有会话中临时使用(全局临时程)。也可以创建在Microsoft®SQL Server™启动时自动运行的存储过程。
存储过程涉及很多的数据处理,整个是一个复杂的过程。它可以接收参数,相当于一个函数。主要目的是用来处理数据。而视图是把现在有数据组合成新的形式展示出来,其目的是用来呈现数据。