目录(点击链接可直接跳转)
目录
写在前面:
全书概要
划分重点
第三章 创建和管理表
第四章 索引与数据完整性
第五章 查询与视图
第六章 T-SQL程序设计
第七章 存储过程与触发器
抽时间总结了下数据库这门课本学期的全部内容
以课本和课后实验作业为参考,筛选了一些觉得相对重点的知识点和例题
汇总和整理了一下,方便复习,也方便以后查看。
文中含有大量例题代码以及章节导图,建议使用电脑访问,纯手打,maybe会有错别字(大雾)
注:参考用书 SQL Server2008数据库应用技术(第二版)(刘卫国刘泽星主编)
注:可以下载本文内容的的PDF版 戳一戳 PDF版下载
注:若博文有问题可以加qq交流:1274221894 备注csdn
全书一共10章
第一章、第二章以及第八、第九、第十章在考试中占比相对较少,所以这里主要总结了三到七章,
另外第二章是创建和管理数据库的语句语法,虽然期末考试涉及较少,但是内容其实蛮重要的,
也单独整理了一下,在另一篇博客里 链接:第二章 创建和管理数据库。
这篇主要汇总了3-7章 如下图
第一章、第二章、第八章、第九章、第十章不考!
(但是关于第二章:要知道如何创建数据库 关于第八章:要知道事务的基本语法)
剩下的 三到七章 如图 红色要求熟练应用(必考) 蓝色要求熟练语法 白色不考
注:下文每章汇总的例题以及知识点是与导图划分的重点一一对应的,方便查阅。
导图
知识点以及例题
3-0(1.4号补充)
在创建表的过程中 表中字段设置有几个需要注意的地方
No.1
字段类型 注意看题目要求 来设置字段类型
常用 char varchar int double date
关于日期型 有好几种表示日期的类型 要看题目要求 来决定用哪个
No.2
检查约束 根据题目要求对字段进行约束
比如 图书编号以B为开头 图书编号 char(5) check(图书编号 like 'B%')
No.3
默认值约束 根据题目要求给字段设置默认值
比如 图书数量默认值为0 图书数量 int default 0
综合例子
创建一个会员表 包含字段有 编号、姓名、性别、注册日期、是否VIP
编号是整型 设置为非空主键 并且是标识列 种子是1 增量为2
姓名是字符型
性别是字符型 只能是男或女 默认是男
注册日期是date型 默认是当前日期
是否VIP是逻辑型
create table 会员
(编号 int not null primary key identity(1,2),
姓名 varchar(10),
性别 char(2) check(性别 in('男','女')) default '男',
注册日期 date default getdate(),
是否VIP bit
)
3-1
创建表和创建临时表
/*创建专业表 共有三列:专业名称(varchar) 成立年份(smalldatetime) 专业简介(varchar)
设置专业名称和成立年份非空 指定专业表保存在primary文件组中*/
create table 专业
(专业名称 varchar(30) not null,
成立年份 smalldatetime not null,
专业简介 varchar(50)
) on [ primary ]
/*创建临时表*/
create table #student
(学号 varchar(8),
姓名 varchar(10),
性别 varchar(2)
)
3-2
更改和删除表
/*在学生表中添加新列‘联系电话’ 且允许为空*/
alter table 学生
add 联系电话 varchar(15) null
/*删除学生表中联系电话列*/
alter table 学生
drop column 联系电话
/*将学生表中专业名称字段改为varchar(50)数据类型 并且不允许为空*/
alter table 学生
alter column 专业名称 varchar(50) not null
删除表
drop table 专业
3-3
维护表(插入和更新)
/*使用insert插入数据 在课程表中插入一行*/
/*按照指定顺序添加行*/
insert 课程 (课程名称,课程编号,课程类别,学分)
values('大学物理','C903‘,'必修',4)
/*不指定顺序 默认按照表中顺序添加行*/
insert 课程 values('C903','大学物理','必修',4)
/*使用updat语句更新表中数据*/
update 课程 set 学分= 学分+1 where 课程类别='必修'
3-4
使用delete删除表中指定行
/*删除课程表中课程编号为C607的行*/
delete from 课程 where 课程编号 ='C607'
/*删除学生表中所有行*/
delete 学生
导图
4-1
首先 创建索引中有些语法需要注意一下
unique 为表或视图创建唯一索引
clustered 创建聚集索引 不指定clustered 则创建非聚集索引
asc | desc 确定特定索引列的升序或者降序 默认值是asc
4-2
创建索引
/*为“图书信息”表的图书编号列创建唯一性索引book_id_ind。*/
create unique index book_id_ind on 图书信息(图书编号)
/*为BookDb数据库的“图书信息”表的“图书编号”字段创建一个非聚集索引,命名为book_index。*/
create index book_index on 图书信息(图书编号)
/*为BookDb数据库的“借阅信息”表的“借阅证号”和“图书编号”字段创建一个复合唯一索引,命名为book_reader_ind。*/
create unique index book_reader_ind on 借阅信息(借阅证号,图书编号)
4-3
查看、更改、删除索引
/*查看索引 查看学生表上的索引*/
exec sp_helpindex 学生
/*更改学生表中索引name_index的名称为student_name_index */
sp_rename '学生.name_index','student_name_index','index'
/*删除索引*/
drop index student_name_index on 学生
/*删除选课表中的主键约束(pk_选课)索引*/
alter table 选课
drop constraint pk_选课
4-4
创建规则
//为读者信息表的联系电话创建一个规则phone_rule,限制所输入的数据为8位或者11位0~9的数字。
create rule phone_rule
as @联系电话 like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
or
@联系电话 like '[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
4-5
将规则绑定到列上和解除绑定
/*使用系统存储过程sp_bindrule将phone_rule规则绑定到读者信息表的“联系电话”列上。*/
exec sp_bindrule phone_rule,'读者信息.联系电话'
/*创建一个规则gd_rule,将其绑定到“读者信息”表的“性别”列上,保证输入的性别值只能是“男”或“女”。*/
create rule gd_rule
as @性别 like '男' or @性别 like '女'
exec sp_bindrule gd_rule,'读者信息.性别'
/*解除绑定在课程表的课程类别列上的规则*/
exec sp_unbindrule '课程.课程类别'
4-6
查看规则和删除规则
/*使用sp_helptext查看gd_rule规则*/
exec sp_helptext gd_rule
/*删除gender_rule规则。*/
exec sp_unbindrule '读者信息.性别' /*先要解绑 才能删除*/
drop rule gender_rule
4-7
创建默认值和查看默认值
/* 创建日期型默认对象df_date,默认值为‘2015-9-1’。*/
create default df_date as '2015-9-1'
/*创建默认值 nationality_default*/
create default nationality_default as '汉族'
/*查看默认值 nationality_default*/
exec sp_helptext nationality_default
4-8
绑定默认值和解绑默认值以及删除默认值
/*使用系统存储过程sp_bindefault将默认对象df_date绑定在读者_备份表的“办卡时间”列上。*/
exec sp_bindefault df_date,'读者_备份.办卡时间'
/*解除默认对象df_date的绑定,并删除之。*/
exec sp_unbindefault '读者_备份.办卡时间'
drop default df_date
4-9
主键约束
/* 为BookDb数据库的“读者信息”表创建主键约束,名称形如PK_列名。*/
alter table 读者信息
add constraint PK_借阅证号 primary key(借阅证号)
/*为BookDb数据库的“借阅信息”表创建联合主键约束,名称形如PK_列名_列名。*/
alter table 借阅信息
add constraint PK_借阅证号_图书编号 primary key(借阅证号,图书编号)
4-10
外键约束
/* 为“借阅信息”表的“借阅证号”添加外键约束,名称形如FK_列名。*/
alter table 借阅信息
add constraint FK_借阅证号 foreign key(借阅证号)
references 读者信息(借阅证号)
/*删除“借阅信息”表中图书编号列的外键约束。重新创建此列外键为级联删除。*/
/*******
注意 要理解部分关键字的含义
references 指定要建立关联的表的名称
on delete{cascade|no action}
如果设置为cascade 当主键表中某行被删除时 外键表中所有相关行将被删除
如果设置为no action 当主键表中某行被删除时 SQL将报错 默认设置是no action
*******/
alter table 借阅信息
drop constraint FK_图书编号
alter table 借阅信息
add constraint FK_图书编号 foreign key(图书编号)
references 图书信息(图书编号)
on delete cascade
4-11
非空约束
/*为读者信息表的“借阅证件类型”字段设置非空约束。*/
alter table 读者信息
alter column 借阅证件类型 varchar(10) not null
/*撤消读者信息表的“借阅证件类型”字段的非空约束。*/
alter table 读者信息
alter column 借阅证件类型 varchar(10) null
4-12
唯一性约束
/* 为读者信息表的“身份证号”字段设置唯一性约束,名称形如UK_列名。*/
alter table 读者信息
add constraint UK_身份证号 unique (身份证号)
4-13
默认约束
/*修改读者信息表的“借阅证件类型”列的默认约束值为“1001”,名称形如DF_列名*/
alter table 读者信息
add constraint DF_借阅证件类型 default '1001' for 借阅证件类型
4-14
检查约束
/*为读者信息表的“办卡时间”列添加检查约束,办卡时间须在’2010-1-1’以后,名称形如CK_列名。*/
alter table 读者信息
with nocheck
add constraint CK_办卡时间
check(办卡时间>'2010-1-1')
/*禁用此检查约束*/
alter table 读者信息
nocheck constraint CK_办卡时间
导图
知识点以及例题
5-1
一些关键字的含义
distinct 去重
例如 查询选课表中的学号 select 学号 from 选课
查询选课表的学号并且去重 select distinct 学号 from 选课
order by <子段名> {desc | asc} 排序
desc 降序
asc 升序(默认是asc)
having 用于组 必须和group by 子句连用
getdate()函数返回当前系统日期
year(出生日期) 函数返回日期参数的年份
avg() 平均值
sum() 求和
count() 统计行数
between...and... 两个数之间
5-2
基础查询(条件查询、函数的使用)
/* 在读者信息表中查询各单位的读者人数。*/
select 单位,count(*) as 人数 from 读者信息 group by 单位
/*将借阅信息表的借阅记录按罚款金额降序进行排序。*/
select *from 借阅信息 order by 罚款金额 desc
/* 对借阅信息表使用GROUP BY查询子句列出各个读者借书的本数。*/
select 借阅证号,count(*) as 借书本数 from 借阅信息 group by 借阅证号
/* 在图书信息表中,查询出版图书数目 前3位的出版单位。*/
select top 3 with ties 出版单位 ,count(*) as 出版图书数 from 图书信息 group by 出版单位 order by 出版图书数 desc
/*查询所有书名中有“数据库”的图书的编号、书名、作者和出版单位。*/
select 图书编号,书名,作者,出版单位 from 图书信息 where 书名 like '%数据库%'
/*查询办卡时间在“2010-1-1”之前的读者的所有信息。*/
select 借阅证号,姓名,性别,单位,联系电话,身份证号,借阅证件类型,办卡时间,卡状态 from 读者信息 where 办卡时间>'2010-1-1'
/* 找出借书超过1本的读者,输出借书证号及所借图书册数。*/
select 借阅证号,count(*) as 借阅数量 from 借阅信息 group by 借阅证号 having count(*) >1
/* 查询在2014年6月份借阅的图书编号和借书人的借阅证号。*/
select 图书编号,借阅证号 from 借阅信息 where 借阅日期 between '2014-6-1' and '2014-6-30'
5-3
使用except和intersect 比较两个查询的结果
except 从左边的查询中返回右边的查询未返回的所有非重复值
intersect 返回左右两边的两个查询均返回的所有非重复值
/* 查询当前没有借书的读者的借阅证号。*/
select 借阅证号 from 读者信息
except
select 借阅证号 from 借阅信息
/*查询读者 'Y00001' 借阅的 '清华大学出版社' 出版的图书的图书编号。*/
select 图书编号 from 借阅信息 where 借阅证号='Y00001'
intersect
select 图书编号 from 图书信息 where 出版单位='清华大学出版社'
5-4
嵌套查询
/*查询现有图书中价格最高的图书,输出书名及作者。(单值和多值两种方法)*/
select 书名,作者 from 图书信息 where 单价=(select MAX(单价) from 图书信息)
select 书名,作者 from 图书信息 where 单价>=all(select 单价 from 图书信息)
5-5
联结查询
/*查询在办卡当天借阅了图书的读者的借阅证号、姓名。*/
select a.借阅证号,a.姓名 from 读者信息 a inner join 借阅信息 b
on a.借阅证号=b.借阅证号 and a.办卡时间=b.借阅日期
/* 查询借阅了“数据库技术与应用”图书的读者的借阅证号、姓名和借阅日期。*/
select a.借阅证号,a.姓名,b.借阅证号 from 读者信息 a,借阅信息 b ,图书信息 c
where a.借阅证号=b.借阅证号 and b.图书编号=c.图书编号 and c.书名='数据库技术与应用'
左外联结 left outer join
返回符合连接条件的行,并且包括左表的没有和右表连接上的记录行,这些行的相应右表字段置为NULL。
右外联结 right outer join
返回符合连接条件的行,并且包括右表的没有和左表连接上的记录行,这些行的相应左表字段置为NULL。
查询所有图书的借阅情况,要求列出书名、借书证号、借阅日期,
没有被借阅的图书的借阅证号值为空。
select a.书名,b.借阅证号,b.借阅日期
from 图书信息 a left outer join 借阅信息 b
on a.图书编号=b.图书编号
5-6
建立视图
/*建立名为v_reader的视图,显示读者的姓名、性别、联系电话和办卡时间。*/
create view v_reader as
select 姓名,性别,联系电话,办卡时间 from 读者信息
/*建立一个名为v_borrow的视图,视图中具有所有读者的借阅证号、姓名、图书名称、借阅日期。使用视图v_borrow查询借阅证号为B00001的学生的借阅信息。*/
create view v_borrow
as select a.借阅证号,a.姓名,b.书名,c.借阅日期 from
读者信息 a join 借阅信息 c on a.借阅证号=c.借阅证号
join 图书信息 b on b.图书编号=c.图书编号
select *from v_borrow where 借阅证号='B00001'
5-7
修改和删除视图
/* 修改视图v_book,使其显示图书的编号、书名、作者、出版单位、单价和分类号。*/
alter view v_book as
select 图书编号,书名,作者,出版单位,单价,分类号 from 图书信息
/* 使用系统存储过程sp_rename将视图v_reader更名为v_reader_info。*/
sp_rename 'v_reader','v_reader_info'
/* 利用视图v_book为“图书信息”表添加一行数据:图书编号为“10170001”、书名为“计算机导论”、作者为“王艺”、出版单位为“清华大学出版社”、单价为“35”、分类号为“17”。*/
insert into v_book
values ('10170001','计算机导论','王艺','清华大学出版社','35','17')
/*利用视图v_book删除图书编号为“10150004”的图书记录。*/
delete from v_book
where 图书编号='10150004'
/* 删除视图v_info。*/
drop view v_info
导图
例子及代码
6-1
变量与常用函数。
cast()函数 将int转换为varchar
len 字符长度
datalength 字节长度
/*定义3个变量,分别赋值'SQL Server'、2008和'R2',连接以后输出'SQL Server 2008 R2'。(cast()函数)*/
declare @a varchar(10)
set @a='SQL Server'
declare @b int
set @b=2008
declare @c varchar(10)
set @c='R2'
select @a+cast(@b as varchar(10))+@c
/*在图书信息表中,输出书名中包含 '应用' 两字图书的图书编号、书名、书名字符数和书名字节数。*/
select 图书编号,书名,LEN(书名) as 书名字符数,DATALENGTH(书名) as 书名字节数 from 图书信息
where 书名 like '%应用%'
6-2
标量值函数 内嵌表值函数 多语句表值函数
/*创建标量值函数borrow_date,根据输入的借阅证号和图书编号,
输出该借阅记录的借阅日期。
调用函数borrow_date,输出借阅证号'B00002'图书编号'10150002'的借阅日期。*/
create function borrow_date(@JYZH char(30),@TSBH char(30))
returns date
as
begin
declare @F date
select @F=(select 借阅日期 from 借阅信息 where 借阅证号=@JYZH and 图书编号=@TSBH)
return @F
end
select dbo.borrow_date('B00002','10150002')
/* 创建内嵌表值函数reader_type,根据输入的读者类别名称,
输出该类读者的借阅证号、姓名、单位、借书本数。
调用函数reader_type,输出 '教师' 的基本信息和借书本数。*/
create function reader_type(@LBMC varchar(40))
returns table
as
return (
select 读者信息.借阅证号,姓名,单位,COUNT(*) as 借书本数 from 读者信息
join 读者类别 on 读者信息.借阅证件类型=读者类别.类别编号
join 借阅信息 on 借阅信息.借阅证号=读者信息.借阅证号
where 类别编号=(select 类别编号 from 读者类别 where 类别名称=@LBMC)
group by 读者信息.借阅证号,姓名,单位
)
select *from dbo.reader_type('教师')
/* 创建多语句表值函数book_info,根据输入的图书编号,
输出该图书的编号、书名、出版社(编号列为主键)。
调用函数book_info,输出编号为'10160001'的图书的信息。*/
create function book_info(@TSBH char(8))
returns @f table
(
编号 char(8),
书名 varchar(50),
出版社 varchar(50)
)
as
begin
insert @f
select 图书编号,书名,出版单位 from 图书信息 where 图书编号=@TSBH
return
end
select *from book_info('10160001')
6-3
修改函数和删除函数
/*修改函数book_info,输出添加一列为所查询图书的'出借本数'。
再次调用函数,输出编号为'10160001'的图书的信息。*/
alter function book_info(@TSBH char(8))
returns @f table
(
编号 char(8),
书名 varchar(50),
出版社 varchar(50),
出借本数 int
)
as
begin
insert @f
select 图书信息.图书编号,书名,出版单位,count(*) as 本数 from 图书信息
join 借阅信息 on 图书信息.图书编号=借阅信息.图书编号 and 借阅信息.图书编号=@TSBH
group by 借阅信息.图书编号,图书信息.图书编号,书名,出版单位
return
end
/* 将函数'book_num_cla'改名为'book_num'。*/
sp_rename 'book_num_cla','book_num'
/* 删除函数book_num。*/
drop function book_num
6-4程序流程控制
/*编写代码计算阶乘和1!+2!+…+10!。*/
declare @x int,@y int,@z int,@sum int
select @x=1,@sum=0
while @x<=10
begin
select @y=1,@z=1
while @y<=@x
begin
select @z=@z*@y
select @y=@y+1
end
select @sum=@sum+@z
select @x=@x+1
end
print @sum
/* 查询图书编号、书名、单价和图书单价类别,
图书单价类别由CASE函数返回,35元以上'小贵',
30元以上'适合',20元以上'便宜',20元以下'超便宜'。*/
select 图书编号,书名,单价,图书单价类别=
case
when 单价>35 then'小贵'
when 单价>30 then'合适'
when 单价>20 then'便宜'
when 单价<20 then'超便宜'
end
from 图书信息
6-5游标
关于游标 有几个关键字注意一下
scroll 表明允许前后滚动
dynamic 动态
一般不做指定默认游标就是可修改的 可以通过指定将其变为只读游标
open close deallocate 打开 关闭 释放 游标
@@fetch_status 全局变量 遍历时候用 ( while @@fetch_status=0 )
/* 在bookDB数据库中,声明reader_cursor游标,
要求返回单位为“信息学院”的读者的借阅证号、姓名和单位信息,
且该游标允许前后滚动和修改。检索游标数据并显示,
不需要使用变量接收数据。关闭并释放游标。*/
declare reader_cursor cursor
scroll dynamic
for
select 借阅证号,姓名,单位 from 读者信息 where 单位='信息学院'
open reader_cursor
fetch next from reader_cursor
while @@fetch_status=0
begin
fetch next from reader_cursor
end
close reader_cursor //关闭游标
deallocate reader_cursor //释放游标
/* 编写一个程序,采用游标方式输出所有读者的借阅图书本数,
包括借阅证号,姓名和借书本数,要求使用变量接收数据并显示。*/
declare @JYZH char(7),@name varchar(11),@cnt int
declare your cursor
for select 读者信息.借阅证号,姓名,COUNT(图书编号) as 借书本数 from 读者信息 left outer join 借阅信息
on 借阅信息.借阅证号=读者信息.借阅证号
group by 读者信息.借阅证号,姓名
open your
fetch next from your into @JYZH,@name,@cnt
while @@FETCH_STATUS=0
begin
select @JYZH as 借阅证号,@name as 姓名,@cnt as 借书本数
fetch next from your into @JYZH,@name,@cnt
end
close your
deallocate your
/* 编写程序,使用游标,将借出本数2本及以上的图书的备注中填入“受欢迎图书”字串内容。*/
declare my cursor
for select 备注 from 图书信息 where 图书编号 in
(select 图书编号 from 借阅信息 group by 图书编号
having COUNT(*) > 1)
for update of 备注
open my
fetch my
while @@FETCH_STATUS=0
begin
update 图书信息 set 备注='受欢迎的图书'
where current of my
fetch my
end
close my
deallocate my
导图
例子及代码
7-1
存储过程的创建、调用执行、查询、删除
/* 创建存储过程pr_proc,输出字母A~Z(char() ascii())。调用执行。*/
create procedure pr_proc as
declare @cnt int
select @cnt=0
while @cnt<26
begin
print char(ascii('A')+@cnt)
set @cnt=@cnt+1
end
exec pr_proc //执行存储过程
/*查询存储过程pr_proc的文本内容,两种方法(sp_helptext; sysobjects syscomments)。*/
--第一种方法嵌套查询
select text from syscomments where id=(
select id from sysobjects where name='pr_proc')
--第二种方法联结
select text from sysobjects join syscomments
on sysobjects.id=syscomments.id
where sysobjects.name='pr_proc'
/* 删除该存储过程pr_proc。*/
drop procedure pr_proc
/* 创建存储过程male_info_proc,输出男读者的借阅证号,姓名和单位。调用执行。*/
create procedure male_info_proc as
select 借阅证号 from 读者信息
where 性别='男'
exec male_info_proc
将存储过程male_info_proc更名为sex_info_proc。
sp_rename 'male_info_proc','sex_info_proc'
修改存储过程sex_info_proc,使其能根据接收的参数’男’或’女’,输出某一性别读者的借阅证号,姓名和单位信息。
alter procedure sex_info_proc @sex char(10)
as
select 借阅证号,姓名,单位 from 读者信息
where 性别= @sex
7-2
触发器的创建、使用、更新和删除
为“图书信息”表创建一个名为del_bk_tr的DELETE触发器,该触发器的作用是禁止删除图书信息表中的记录,显示'不能删除“图书信息”表中的记录。'。
create trigger del_bk_tr on 图书信息
instead of delete
as select '不能删除“图书信息”表中的记录'
为“借阅信息”表建立一个名为insert_brw_tr的INSERT触发器,当用户向“借阅信息”表中插入记录时,如果插入的记录是在读者信息表没有的借阅证号或者在图书信息表中没有的图书编号,则提示用户'不能插入记录,借阅证号或图书编号非法。',不插入记录(删除已插入记录);否则提示'记录插入成功。'。
create trigger insert_brw_tr on 借阅信息
after insert
as
declare @jyzh varchar(20),@tsbh varchar(20)
select @jyzh=(select 借阅证号 from inserted)
select @tsbh=(select 图书编号 from inserted)
if not exists (select 借阅证号 from 读者信息 where 借阅证号=@jyzh)
begin
delete from 借阅信息 where 借阅证号=@jyzh
print '不能插入记录,借阅证号或图书编号非法。'
end
if not exists (select 图书编号 from 图书信息 where 图书编号=@tsbh)
begin
delete from 借阅信息 where 图书编号=@tsbh
print '不能插入记录,借阅证号或图书编号非法。'
end
if exists (select 借阅证号 from 读者信息 where 借阅证号=@jyzh) and exists (select 图书编号 from 图书信息 where 图书编号=@tsbh)
begin
print '记录插入成功。'
end
为“读者信息”表创建一个名update_bk_tr的UPDATE触发器,该触发器的作用是禁止更新读者信息表中“借阅证号”字段的内容,并显示'不能更改借阅证号字段内容。'。
create trigger update_bk_tr on 读者信息
after update
as
declare @rno varchar(20),@bno varchar(20)
select @rno=借阅证号 from inserted
select @bno=借阅证号 from deleted
if @rno!=@bno
begin
select '不能更改借阅证号字段内容。'
update 读者信息 set 借阅证号=@bno where 借阅证号=@rno
end
update 读者信息 set 借阅证号='B00012',姓名='张小宇' where 借阅证号='B00001'
使用T-SQL语句DROP TRIGGER删除update_bk_tr触发器。
DROP TRIGGER update_bk_tr
为“图书信息”表建立删除触发器del_bk_tr,要求当图书信息表的记录被删除后,借阅信息表中相应的记录也能自动删除,并显示'借阅信息表中有XX条记录也被删除。'。
create trigger del_bk_tr on 图书信息
after delete
as
delete from 借阅信息 where 借阅证号=(select 借阅证号 from deleted)
declare @smg varchar(50)
select @smg='借阅信息表中有'+str(@@rowcount)+'条记录也被删除。'
select @smg
下面两个是较难的例子
用触发器 综合了前面章节的内容 考试应该不会考到这么难的
1
查询所有专业的平均成绩并创建一个新的“专业平均成绩”表,包含两个属性:专业名称,平均成绩。
在选课表上创建一个监听插入和修改操作的触发器,当有记录被插入或者修改的时候,查询被插入或修改记录的学生所在专业的平均成绩,与专业平均成绩表中记录对比:
- 如果平均成绩相同,则不作更改,显示“专业平均成绩无变化。”;
- 如果平均成绩不同,则将专业成绩表中的记录更新为最新值,并显示“专业平均成绩变化,并已更新!”。
select 专业名称,平均成绩=avg(成绩) into 专业平均成绩 from 学生 s join 选课 sc
on s.学号=sc.学号 group by 专业名称
create trigger tr_sc_avg on 选课
after insert,update as
declare @a varchar(10),@b varchar(10),@new float,@old float
select @a=学号 from inserted
select @b=专业名称 from 学生 where 学号=@a
select @new=avg(成绩) from 学生 join 选课 on 学生.学号=选课.学号
where 专业名称=@b
select @old=平均成绩 from 专业平均成绩 where 专业名称=@b
if @new=@old
print '专业平均成绩无变化。'
else
begin
update 专业平均成绩 set 平均成绩=@new where 专业名称=@b
print '专业平均成绩变化,并已更新!'
end
2
在选课表中创建一个监听修改操作的触发器,如果有记录被修改,则检查被修改记录的学生的平均成绩,如果平均成绩不小于85则更新学生表中的“有否奖学金”记录为1,打印“***同学的平均成绩为:***分,可得到奖学金!”;如果该学生平均成绩小于85分,但是其入学成绩不小于600分,则更新学生表中的“有否奖学金”记录为1,打印“***同学的入学成绩为:***分,可得到奖学金!”;如果平均成绩小于85,并且入学成绩小于600,则更新学生表中的“有否奖学金”记录为0,打印“***同学的入学成绩为:***分,平均成绩为***分,无法得到奖学金!”。
create trigger tr_sc_update on 选课
after update as
declare @sno varchar(20),@sno_avg float
declare @smg varchar(250),@name varchar(20)
select @sno=学号 from inserted
select @sno_avg=avg(成绩) from 学生 join 选课 on 学生.学号=选课.学号
where 学生.学号=@sno group by 学生.学号
if @sno_avg<85
begin
declare @rxcj float
select @rxcj=入学成绩 from 学生 where 学号=@sno
if @rxcj>=600
begin
update 学生 set 有否奖学金=1 where 学号=@sno
select @name=姓名 from 学生 where 学号=@sno
select @smg=@name+'同学的入学成绩为:'+str(@rxcj)+'分,可得到奖学金!'
select @smg
end
else
begin
update 学生 set 有否奖学金=0 where 学号=@sno
select @name=姓名 from 学生 where 学号=@sno
select @smg=@name+'同学的入学成绩为:'+str(@rxcj)+'分,平均成绩为'+str(@sno_avg)+ '分,无法得到奖学金!'
select @smg
end
end
else
begin
update 学生 set 有否奖学金=1 where 学号=@sno
select @name=姓名 from 学生 where 学号=@sno
select @smg=@name+'同学的平均成绩为:'+str(@sno_avg)+'分,可得到奖学金!'
select @smg
end
3
在Deal表上面建立一个监听插入操作的触发器,当有新的购买记录插入表时:检查新购买商品的库存是否足够;并且检查该用户的余额是否足够支付该订单;如果商品库存不足或者用户余额不足,则删除Deal表中该条记录,并且提示“库存不足或者用户余额不足!无法购买!”;如果商品库存足够并且余额也足够,则更新商品表中该商品库存,以及用户表中该用户的订单数量加一,然后提示“购买成功 用户编号:*** 商品号:***”(***是具体的用户编号或者商品号内容)
create trigger www on Deal
after insert
as
declare @spbh char(4),@spsl smallint,@spjg float,@yhye float,@kc smallint,@yhbh char(8)
select @spbh=Gno from inserted
select @spsl=Dnum from inserted
select @spjg=Gprice from Goods where Gno=@spbh
select @yhbh=Uno from inserted
select @yhye=Umoney from Users where Uno=@yhbh
select @kc=Gnum from Goods where Gno=@spbh
if(@kc<@spsl or @yhye<@spjg*@spsl)
begin
print '库存不足或者用户余额不足!无法购买!'
delete from Deal where Gno=@spbh and Uno=@yhbh
end
else
begin
print'购买成功 用户编号:'+@yhbh+' 商品号:'+@spbh
update Goods set Gnum=Gnum-@spsl where Gno=@spbh
update Users set Ubuy=Ubuy+1 where Uno=@yhbh
end
--测试
insert Deal
values ('20160002','B003','2018-12-12',3)
drop trigger www