数据库学习笔记(基础)

发布时间:2024年01月07日

目录

一、数据库

创建数据库:

删除数据库:

二、表

1、直接创建表

2、根据已有表创建新表

3、删除表

4、修改表

(1)增加列

(2)删除列

(3)修改数据类型

(4)修改列名

5、表数据

(1)插入表数据

(2)删除表数据

(3)修改表数据

6、表约束

(1)创建表时进行约束

(2)使用alter语句添加约束

三、查询

1、单表查询

(1)基本查询

(2)条件查询

1)比较大小

2)确定范围

3)确定集合

4)字符匹配

5)空值查询

(3)投影查询(查询特定字段)

(4)过滤查询

(5)聚合查询

常用聚合函数

注意:

2、多表查询

3、连接查询

(1)等值查询(不删除重复列)

(2)自身连接(等值连接)

(3)复合条件连接

(4)内连接(本质是等值连接)

(5)外连接

1)左连接(left join)或左外连接(left outer join):返回左表中的所有行

2)右连接(right join)或右外连接(right outer join):返回右表中的所有行

3)全连接(full join)或全外连接(full outer join):返回左表和右表的所有行,无对应信息使用NULL值返回

4、嵌套查询

(1)不相关子查询:

(2)相关子查询:

1)带有in谓词的子查询:

2)带有比较运算符的子查询:

3)带有any或all谓词的子查询

4)带有exists谓词的子查询:

5、集合查询

四、存储过程

1、创建存储过程

(1)无参

(2)带输入参数(带默认值)

(3)带输入和输出参数

2、修改存储过程

3、删除存储过程

五、触发器

1、创建触发器

2、删除触发器


该学习笔记由知识点和例题组成,例题是为了帮助大家更好地理解知识点。

一、数据库

创建数据库:
create database 数据库名称;
删除数据库:
drop database 数据库名称;

二、表

1、直接创建表
create table 表名
(列名1 数据类型1 约束1,
列名2 数据类型2 约束2,
......);
--约束可有可无,根据需求设置,详细见第6点
2、根据已有表创建新表
--只有表结构
select * into newtable from 已有表名 where 1=2;
--有表结构和表数据
select * into newtable from 已有表名;
3、删除表
drop table 表名;
4、修改表
(1)增加列
alter table 表名
add 列名 数据类型;
(2)删除列
alter table 表名
drop column列名;
(3)修改数据类型
alter table 表名
alter column 列名 数据类型;
(4)修改列名
sp_rename '表名.旧列名','新列名','column';

--将Student表中列名ID改为Sno
sp_rename 'Student.ID','Sno','column';
5、表数据
(1)插入表数据
--一行一行插入
insert into 表名(列名1,列名2,列名3)
values(内容1,内容2,内容3);	--第一行数据
values(内容1,内容2,内容3);	--第二行数据
......

--多行插入
insert into 表名(列名1,列名2,列名3)
values (
内容1 内容2 内容3,    --第一行数据
内容1 内容2 内容3,    --第二行数据
内容1 内容2 内容3     --第三行数据
);
(2)删除表数据
delete from 表名 where 条件;
(3)修改表数据
--将满足条件的列名1的数据改为数据1,列名2的数据改为数据2
update 表名
set 列名1=数据1,列名2=数据2
where 条件;

--eg:
--将选修81002课程的所有学生的成绩减少5分
update SC
set Grade=Grade-5
where Cno=’81002’;
--将Sage>18的学生的Name改为“小明”
update Student
set Sname=大明
where Sage>18;
6、表约束
(1)创建表时进行约束
create table 表名
(列名1 数据类型1,约束类型1
列名2 数据类型2,约束类型2);
(2)使用alter语句添加约束
--添加主键约束
alter table 表名 add constraint 约束名 primary key(列名);
--添加唯一性约束
alter table 表名 add constraint 约束名 unique(列名);
--添加check约束
alter table 表名 add constraint 约束名 check(列名=values1 or 列名=values2)
--添加外键约束
alter table 表名 add constraint 约束名 foreign key(列名) reference 关联表名(列名) --该列名需是表的主键

三、查询

1、单表查询
(1)基本查询
select * from 表名;

--查询Stu表
select * from Stu;
(2)条件查询
1)比较大小
--①查询满足条件的数据
select * from 表名 where 条件;
--eg:
    --输出年龄大于18岁的学生
    select * from Student where age>18
    --查询2000年及2000年后出生的所有学生的姓名和性别
    select Sname,Ssex
    from Student
    where year(birthday)>=2000
    --查询全体学生的姓名及出生年份
    select Sname,year(getdate())-Sage as birthday
    from Student;
    --year()返回指定日期的年份,getdate()返回当前的系统日期和时间


--②输出同时满足条件1和条件2的学生
select * from 表名 where 条件1 and 条件2;
--eg:
    --输出年龄大于18且性别为男的学生
    select * from Student whare age>18 and sex=’男’

--③输出满足条件1或条件2其中一条的数据
select * from 表名 where 条件1 or 条件2;
--eg:
    --查询年龄大于18的学生,或者年龄在20岁以上的女学生。
    select * from Student where Sage>18 or (Sage>=20 and Ssex=’女’)

--④输出不满足条件的数据
select * from 表名 where not 条件

优先级:()>not>and>or
2)确定范围
select 列名 from 表名 where 列名 between 开始值 and 结束值

--查询年龄(不)在20~23岁的学生
select Sname
from Student
where extract(year from current_date) – extract(year fro Sbirthday)
(not) between 20 and 23
--查询10后学生信息
select * from Student
where year(birthday) between 2010 and 2019
--查询巨蟹座学生信息(巨蟹座8/23-9/22)
select * from Student
where birthdat between datefromparts(year(birthday),8,23) and 
datefromparts(year(birthday),9,22)
    --datefromparts(year,month,day)函数
--查询出16-20岁之间并且成绩在80-100之间的学生
select * from Student,SC
where (datediff(year,birthday,getdate()) between 16 and 20)
and (Grade between 80 and         100) 
    --datediff(year,birthday,getdate()) 取出当前系统时间和birthday的年份进行间隔计算
    --datediff()函数用于计算两个日期之间的间隔
3)确定集合
--查询列名3中数据(不)为数据1或数据2的对应的列名1和列名2
select 列名1, 列名2…
from 表名
where 列名3 (not) in (数据1, 数据2)

--查询计算机科学与技术、信息安全专业的学生的姓名和性别
select Sname, Ssex
from Student
where Smajor in (‘计算机科学与技术’,’信息安全’);
4)字符匹配
--查找等于指定字符串的值
select * from 表名 where 列名 like “查询值”

--查找名字以张开头的同学
select * from Student where Name like ‘张%’
--查看2018级学生的姓名		
select Sname
from Student
where Sno=’2018%’
--查询名字含有‘浩’和‘骏’的学生信息
select * from Student
where Sname like ‘%[浩骏]%’
--查询名字含有‘亮’的学生姓名
select Sname from Student
where Sname like ‘%亮%’
--查询姓陈且名字是两个字的员工信息
select * from Student
where Sname like ‘陈_’

--查找不等于指定字符串的值
select * from 表名 where 列名 not like “查询值”
5)空值查询
--查询缺少成绩的学生的学号和相应课程号
select Sno, Cno
from SC
where Grade is null;		
--查询没有填写户籍地的学生姓名(Shome为空或者Shome为空字符串)
select Sname
from Student
where Shome is null or Shome=’’;

(3)投影查询(查询特定字段)
select 列名1,列名2 from 表名
select 列名1,列名2 from 表名 where 条件

--查询满足年龄>18的学生的学号和名字
select StudentID,Name from Student where Age >18	
(4)过滤查询
select distinct 列名1,列名2 from 表名
--distinct 将查询结果中的重复的数据只留下一个

--查询学生表中的学生来自哪些城市(一个城市可能会有多个学生)
select distinct City from Student	
--查询成绩不合格的学生学号(一个学生可能有多门成绩不合格)
select distinct Sno 
from SC 
where Grade<60	
(5)聚合查询
--查询表中数据条数(行数),别名可有可无,别名数据为count(*)的数据
select count(*) 别名 from 表名;

--查询Student表中学生人数Studentnum
select count(*) Studentnum from Student;

select count(*) 别名 from 表名 where 条件;

--查询Student表中年龄>20的学生人数Studentnum
select count(*) Studentnum from Student where Age>20;	
常用聚合函数
--查询表中列名1数据平均数
select avg(列名1) from 表名;

--查询表中列名1数据的总数
select sum(列名1) from 表名;

--查询表中列名1数据的最大值
select max(列名1) from 表名;

--查询表中列名1数据的最小值
select min(列名1) from 表名;	

(6)排序查询:order by字句只能用于对最终查询结果排序,不能对中间结果排序;任何情况下,order by字句只能出现在最后。?对集合操作结果排序时,order by字句可使用数字指定排序属性。

--把表中的数据根据列名中的数据从小到大排序
select * from 表名
order by 列名 asc;

--学生按照年龄从小到大排序
select * from Student order by Age asc;	

--把表中的数据根据列名中的数据从大到小排序
select * from 表名
order by 列名 desc;

--查询学生信息根据专业名称长度降序排序
select * from Student order by len(Dname) desc;
--查询所有学生信息,根据名字说字母拼音降序升序排序
select * from Student order by Sname collate chinese_prc_cs_as_ks_ws asc;

--把表中的数据根据列名1排序完后,再根据列名2排序(即列名1数据相同的根据列名2排序)
select * from 表名
order by 列名1 asc,列名2;

--学生按照年龄排序,相同age的学生按照sex排序
select * from Student order by Age asc,Sex;	

--列名2排序,列名2相同列名3排序
select 列名1,列名2,...
from 表名
order by 列名2 asc|desc, 列名3 asc|desc;	

查询出分数最高的学生姓名(分数最高的可能不止一个人,可能会有并列第一名,则需要加上with ties)
select top 1 with ties *
from SC
order by Grade desc
--或
    select * from SC where Grade=(select max(Grade) from SC)
--查询出前10%学生中的成绩最高的信息(前10%学生中也有可能出现成绩重复的情况,需要加上with ties)
select 10 precent with ties * from SC order by Grade desc

(7)分组聚合查询

select 列名1, count(*) from 表名 group by 列名1;	

--学生表中每个城市有多少个学生
select City, count(*) from Student group by City;		
select 列名1, 列名2, count(*) from 表名 group by 列名1,列名2;	
--学生表中每个城市以及每个性别有多少学生
select City, Sex, count(*) from group by City, Sex;	
注意:

????????where语句中不能直接使用聚合函数

????????havig 是对分组之后的结果进行筛选

2、多表查询
select * from 表名1,表名2;
--查询Student表和Course表
select * from Student, Course;

--把表1中的列1改名为列别名1,表2中的列2改名为列别名2,输出别名1和别名2的数据
select 表名1.列名1 as 列别名1, 表名2.列名2 as 列别名2
from 表名1, 表名2;
--把学生表中的学号列改名为SID,把课表中的课程号改名为CID,查询结果输出为SID和CID的数据
select Student.StudenID as SID, Course.CourseID as CID
from Student, Course;

select 表别名1.列名1 as 列别名1, 表别名2.列名2 as 列别名2
from 表名1 as 表别名1, 表名2 as 表别名2;
--把学生表改名为S并把学生表中的学号列改名为SID放在S表中输出,把课程表改名为C并把课程表中
select S.StudentID as SID, C.CourseID as CID
from Student as S, Course as C

select 表别名1.列名, 表别名2.列名
from 表名1 as 表别名1, 表名2 as 表别名2 where 条件
--把满足学生表中的课程号=课程表中的课程号的学生的学号和课程号输出,即查询选择了某些课程的学生有哪些
select S.StudentID, C.CourseID
from Student as S, Course as C where S.CourseID=C.CourseID;
3、连接查询
(1)等值查询(不删除重复列)
--查询每个学生及其选修课程的情况(涉及两个表)
select Student.*,SC.*
from Student,SC
where Student.Sno=SC.Sno

--查询计算机系(CS)学生的学号,姓名,所在系,选修的课程号,课程名和成绩(涉及三个表)
select SC.Sno,Sname,Sdept,SC.Cno,Cname,Grade
from Student,SC,Course
where Student.Sno=SC.Sno	--连接条件
and Course.Cno=SC.Cno
and Sdept=’CS’
(2)自身连接(等值连接)
--查询每一门课的直接先修课的课程名(对一个表进行两次查询),查询结果如下第二张图
select a1.Cname,a2.Cname
from Course a1, Course a2
where a1.Cpno=a2.Cno

--查询每一门课的间接先修课的课程号,查询结果如下第三张图
select a1.Cno,a2.Cpno
from Course a1,Course a2
where a1.Cpno=a2.Cno

--课程与先修课的详细关系如下图:

备注:数据库的先修课程号Cpno是5,课程号Cno 5对应的课程是数据结构,即数据库的先修课程是数据结构。数据库的先修课程号Cpno是5,课程号Cno 5对应的课程是数据结构,数据结构的先修课程Cpno号是7,课程号Cno 7对应的课程是C语言,即数据库的间接先修课程号是C语言。

--查询同时先修2号课程和3号课程的学生的学号。(SC表如下图)
select a.Sno
from SC a,SC b
where a.Sno=b.Sno	//连接条件
and a.Cno<>b.Cno	(a.Cno与b.Cno不相等)
and a.Cno=2
and b.Cno=3

(3)复合条件连接
--查询先修1号课程且成绩在90分以上的所有学生的姓名,性别及所在系
select Sname,Ssex,Sdept
from Student,SC
where Student.Sno=SC.Sno	--连接条件
and Cno=1 
and Grade>=90

--查询每个学生的学号、姓名、选秀的课程名及成绩
select Studnet.Sno,Sname,Cnname,Grade --由于SC和Student表中都含有Sno,因此需要指明是哪个表的Sno
from Student,Course,SC
where Student.Sno=SC.Sno and Course.Cno=SC.Cno;
(4)内连接(本质是等值连接)
--在满足条件的数据中输出指定列数据
select 表名1.列名1, 表名2.列名1…
from 主表名
join 连接表名 on 条件;

--查询所有的学生信息及其选修课程情况
select Student.*,SC.*
from Student join SC
on Student.Sno=SC.Sno	
--返回的是满足Student.Sno=SC.Sno的学生的信息,对于那些没有选修课程的学生信息是不返回的
(5)外连接
1)左连接(left join)或左外连接(left outer join):返回左表中的所有行
--查询所有的学生信息及其选修课程情况
select Student.*,SC.*
from Student left join SC
on Student.Sno=SC.Sno;	
--返回的是左表当中的所有行及其在右表中对应的行,如果左表的行在右边找不到对应的信息则会用NULL输出,即可以返回满足Student.Sno=SC.Sno的学生的信息,也可以返回那些没有选修课程的学生信息

(左表是黄框,右表是绿框,右连接/内连接/等值连接返回篮筐信息,左连接返回红框信息)

2)右连接(right join)或右外连接(right outer join):返回右表中的所有行
3)全连接(full join)或全外连接(full outer join):返回左表和右表的所有行,无对应信息使用NULL值返回
4、嵌套查询

子查询限制:不能使用order by子句

????????????????????????层层嵌套方式反应SQL语言的结构化

????????????????????????有些嵌套查询可以用连接运算替代

(1)不相关子查询:

内查询和外查询没有关联(子查询不依赖于父查询),由里向外逐层处理,即每个子查询在上一级查询处理之前求解,子查询的结果用于建立其父查询的查找条件。

--查询选修2号课程的学生姓名
select Sname
from Student
where Sno in
(select Sno
from SC
where Cno=2);
--先查出选修了2号课程的学生号,再从选出的学生号中查询对应的学生姓名
(2)相关子查询:

子查询依赖于父查询

1)带有in谓词的子查询:

父查询和子查询之间用in进行连接,子查询的结果是一个集合

--查询与“刘晨”在同一个系学习的学生
select  Sno,Sname,Sdept
from Student
where Sdept in
(select Sdept
from Student
where Sname=”刘晨”);
--或
select S1.Sno,S1.Sname,S1.Sdept
 from Student S1,Student S2
where S1.Sdept=S2.Sdept,S2.Sname=”刘晨”

--查询选修了课程名为“信息系统”的学生学号和姓名
select Sno,Sname
from Stduent
where Sno in
(select Sno
from SC
where Cno in
(select Cno
from Course
where Cname=”信息系统”));
--或
select Student.Sno,Student.Sname
from Student,SC,Course
where Student.Sno=SC.Sno and SC.Cno=Course.Cno and Course.Cname=”信息系统”;
2)带有比较运算符的子查询:

子查询一定要跟在比较运算符之后

--找出每个学生超出它选修课程平均成绩的课程号(SC表如下图)
select Cno from SC where Grade >
(select avg(Grade) from SC group by Sno)

select Sno,Cno
from SC x
where Grade >	    --95001的各科成绩与平均成绩作比较
(select avg(Grade)
from SC y
where y.Sno=x.Sno)	--求95001的平均成绩

3)带有any或all谓词的子查询

any:任意一个值

all:所有值

--查询其他系中比IS系任一学生年龄小的学生姓名和年龄
select Sname,Sage
from Student
where Sage < any
(select Sage
from Student
where Sdept=’IS’)	--先查询出IS系的所有年龄
and Sdept<>’IS’;		--其他系

--查询其他系中比IS系所有学生年龄都大的学生姓名和年龄
select Sname,Sage
from Student
where Sage <all
(select Sage
from Student
where Sdept=’IS’
)
order by Sage desc;
4)带有exists谓词的子查询:

不返回任何实际数据,只产生逻辑真值“true”和逻辑假植“false”(not exists和exists后面的select语句,查询内容必须为*)

--查询所有没选修1号课程的学生姓名
select Sname
from Student
where not exists	--不符合条件的就输出
(select *
from SC
where Sno=Student.Sno and Cno=1);	--查询选修了课程号1的学生的信息

--查询所有选修了1号课程的学生姓名
select Sname
from Student
where exists
(
select *
from SC
where Sno=Student.Sno and Cno=1);

--查询选修了全部课程的学生姓名。(即没有一门课程他是不选的)
select Sname
from Student
where not exists
(
select *
from Course
where not exists
(select *
from SC
where Student.Sno=Sno and Course.Cno=Cno))

--查询至少选修了学生95002选修的全部课程的学生学号
select Sno
from SC X
where not exists
(select *
from SC Y
where Sno=’95002’ and not exists
(select *
from SC
where Sno=X.Sno and Cno=Y.Cno));
5、集合查询

并查询:参加union操作的各结果表的列数必须相同;对应项的数据类型也必须相同

<查询块>

union

<查询块>

--查询选修1号课程和2号课程学生的学号
select Sno from SC where Cno=1
union
select Sno from SC where Cno=2;

四、存储过程

1、创建存储过程

利用SSMS图形化界面工具创建存储过程:数据库|可编程性|存储过程|新建存储过程|在模板输入Transact-SQL语句|执行

利用Transact-SQL语句创建存储过程

(1)无参

--创建存储过程(不带参数)

????????go

????????create procedure 存储过程名

????????as

????????????????sql语句;

--执行

????????exec 存储过程名;

--在教学库创建无参存储过程,查询每个学生的平均成绩
go
create procedure student_avg
as
    select Sno,avg(Grade) as avgrade from SC group by Sno;

--执行存储过程
exec student_avg;
(2)带输入参数(带默认值)

--创建存储过程(带输入参数)

????????go

????????create procedure 存储过程名称

????????@输入参数1 数据类型, / @输入参数1 数据类型=默认值 --输入参数

????????@输入参数2 数据类型

????????...

????????as

????????????????select ..... where 列名1=@输入参数1 and 列名2=@输入参数2;

--执行存储过程

????????exec 存储过程名称 @输入参数1='值'/值,@输入参数2='值'/值

--1)带输入参数
--向学生表中添加一行数据的存储过程
create procedure astu
@num char(6),
@name char(20),
@sex char(2)	--定义参数(每列所对应的值)
as
insert into Student(Sno,Sname,Ssex)	--添加数据所对应的列名
values(@num,@name,@sex)	--调用参数
--执行astu:
exec astu ‘200501’,’张力’,’女’

--创建存储过程,通过学号查询某个学生的学号,姓名,所选课程的课程号,成绩
create procedure getStudent1
@sno char(11)
as
select Student.Sno,Sname,Course.Cno,final
from Student join Score
on Student.Sno=Score.Sno
where Student.Sno=@sno 
--执行getStudent1:
exec getstudent1 ‘18122221324’

--向学生表中添加一行数据的存储过程
create procedure astu
@num char(6),
@name char(20),
@sex char(2)	--定义参数(每列所对应的值)
as
insert into Student(Sno,Sname,Ssex)	--添加数据所对应的列名
values(@num,@name,@sex)	--调用参数
--执行:
exec astu ‘200501’,’张力’,’女’

--创建存储过程,通过学号查询某个学生的学号,姓名,所选课程的课程号,成绩
create procedure getStudent1
@sno char(11)
as
select Student.Sno,Sname,Course.Cno,final
from Student join Score
on Student.Sno=Score.Sno
where Student.Sno=@sno 
--运行:
exec getstudent1 ‘18122221324’

--2)带输入参数和默认值
--向学生表中添加一行数据的存储过程
go
create procedure addstu
@sno varchar(10)='20180010',
@sname varchar(20)='郭凤琳',
@sex char(4)='女',
@sbirthday date='2003-01-08',
@smajor varchar(40)='计算机科学与技术'
as
	insert into Student values (@sno,@sname,@sex,@sbirthday,@smajor)
--insert into Student(Sno,Sname) values (@sno,@sname)
--执行:
exec addstu @sno='20180011',@sname='易伟蕊',@sex='女',@sbirthday='2003-09-01',@smajor='计算机科学与技术';
exec addstu;
--没有指定输入参数的值,则按照默认值去执行;如果指定了输入参数的值,则输入指定参数的值

--创建存储过程,通过学号查询某个学生的学号,姓名,所选课程的课程号,成绩。如果没有提供学号,则返回所有学生的有关信息。
create procedure Getstudent2
@sno char(11)=’%’
as
select Student.Sno,Sname,Cno,Grade
from Student,SC
where Student.Sno=SC.Sno and Student.Sno like rtrim(@sno)
--运行:
exec Getstudent2 ‘18122221324’	
--或 
exec Getstudent(输出所有满足条件的学生信息)
--Rtrim()它用于去掉字符串末尾的空白字符或其他指定字符。

--从三个表的连接中返回指定学生的学号、姓名所选课程名称及所选课程成绩。该存储过程在参数中使用模式匹配,如果没有提供参数,则使用预设的默认值。
create procedure Stugrade1
@sname char(30)=’%’
as
select Student.Sno,Student.Sname,Course.Cname,SC.grade
from Student inner join SC on Student.Sno=SC.Sno
 inner join SC on Course.Cno=SC.Cno
where Sname like rtrim(@sname)	
--rtrim()函数用于裁切字符串的开头和尾部的空格,制表,回车符。
--运行:
exec Stugrade1 ‘王%’		
--或 
exec Stugrade1 default
--Rtrim()它用于去掉字符串末尾的空白字符或其他指定字符。

--从三个表中查询某人指定课程的成绩和学分。该存储过程接受与传递参数精确匹配的值。
create procedure Stugrade2
@sname char(10)
@cname char(30)
as
select Student.Sname,SC.grade,Course.credit
from Student inner join SC on Student.Sno=SC.Sno
inner join Course on Course.Cno=SC.Cno
where Student.Sname=@sname and Course.Cname=@cname
--运行:
exec Stugrade ‘刘晨’,‘数据库系统概论’

--创建存储过程,按照指定及格分数线,通过课程号查询该课程及格人数。及格分数线默认为60.
go
create procedure jige
@jigegrade int=60,
@cno varchar(20)
as
		select count(*) as 及格人数
		from SC
		where Grade>=@jigegrade and Cno like @cno;
--分别按照默认及格线和90分及格,查询C05103及格的人数
exec jige @jigegrade=65,@cno='81003';
exec jige @cno='81003';
(3)带输入和输出参数

--创建存储过程(带输入输出参数):

go

create procedure 存储过程名称

@输入参数 数据类型, / @输入参数 数据类型=默认值 --输入参数

@输出参数 数据类型 output --输出参数

as

select ..... where 列名=@输入参数;

--执行

declare

@my输入参数 数据类型, --输入参数

@my输出参数 数据类型 output --输出参数

set @my输入参数='值'/值

exec 存储过程名称

@my输入参数,

@my输出参数 output

print @my输出参数

--创建一个存储过程,用于返回指定学号学生所选课程的总成绩
crate procedure pro_stu3
@num char(6),
@g int output --输出参数
as
    select @g=sum(grade)
    from SC
    where Sno=@num and grade is not null
--运行:
declare @t_grade int, @Sno
set @Sno=’12345’    --指定学号为123345
exec pro_stu3
@Sno,
@t_grade output
print @Sno+’的总成绩是:’+str(@t_grade);

--创建存储过程,查询学号为20180001学生所选课的平均成绩
go
create procedure avgs
@sno varchar(10), 
@avg float output --输出参数
as
	select @avg=avg(Grade) from SC where Sno=@sno;
--执行:
declare
@mysno varchar(10),
@myavg float
set @mysno='20180001'
exec avgs 
@mysno,
@myavg output
print @mysno+'的平均成绩:'+str(@myavg);

--用于计算一个指定学生的总学分,存储过程中使用了一个输入参数和一个输出参数
create procedure t_credit
@sname char(15)
@t_credit int output
as
    select @t_credit=sum(credit)
    from Student inner join SC on Student.SC=SC.Sno
    inner join Course on SC.Cno=Course.Cno
    where Student.Sname=@sname
--执行
declare
@myname char(15),
@mysumc int
set @myname='小明'
exec t_creadit
@myname,
@mysumc output
print @myname+'的总学分为'+str(@mysumc);
2、修改存储过程
--修改存储过程Getavg,除了输出指定学生的平均成绩外,还输出该学生选修的课程的总门数。存储过程中使用一个输入参数(学号)和两个输出参数(平均成绩和选修课程门数)
go
alter procedure avgs
@sno nchar(10),
@avg float output,
@sumc int output
as
	select @avg=avg(Grade),@sumc=count(Cno) from SC where Sno=@sno;
--执行;
declare
@mysno nchar(10),
@myavg float,
@mysumc int
set @mysno='20180001'
exec avgs
@mysno,
@myavg output,
@mysumc output
print @mysno+'的平均成绩为'+str(@myavg)+',总课程数为'+str(@mysumc);
3、删除存储过程
drop procedure 存储过程名称;

五、触发器

触发器工作原理:触发器出发时,系统自动在内存中创建deleted表或inserted表;只读,不允许修改;触发器执行完成后,自动删除。

inserted表:临时保存了插入或更新的记录行

deleted表:临时保存了删除或更新的记录行

DML触发器(数据操作功能):数据的更改操作引发的触发器。(update、delete、insert

DDL触发器(数据定义功能):对数据库对象的操作引发执行的触发器。(create、alter、drop、grant、deny、revoke)

1、创建触发器

利用SSMS图形化界面命令创建触发器:数据库|表|触发器|新建触发器|执行

利用SQL命令创建触发器

--为学生表创建一个简单DML触发器,在插入和修改数据时,都会自动显示提示信息
create trigger reminder
on Student
for insert,update
as
print’你在插入或修改学生表的数据’
--触发语句:
insert into student values(‘2021350’,’小明’,’女’)

--为学生表创建一个DML触发器,在插入和修改数据时,都会自动显示所有学生的信息。
create trigger s_info
on Student
for insert,update
as
select * from Student
--触发语句:
update Student
set Sname=’梁小欣’
where Sname=’梁欣’	--把梁欣改为粱小欣

--在学生表上创建一个DELETE类型的触发器,删除数据时,显示删除学生的个数。
go
create trigger dsum
on Student
for delete
as
print '删除学生个数为:'+str(@@rowcount);
--触发语句:
delete from Student
where Sno=’2021350’
--@@Rowcount:返回sql语句所影响的数据行数.

--级联删除:删除学生表中某个学号,则该学号在SC表中的相关信息也会自动删除
create trigger Del 
on Sudent
after delete --触发时机是在Student表上出现delete操作
as
begin
delete from SC where Sno in (select Sno from deleted)    --在deleted表中查询Sno,然后在SC表中删除该学号信息
end;
--触发语句:
delete from student where Sno=’00101003’
2、删除触发器
drop trigger 触发器名称;

文章来源:https://blog.csdn.net/m0_70859191/article/details/135395219
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。