做MSSQL实验时的一些理解

数据库中有3张表,使用t-sql检索数据 s: sno学号, sname姓名, dept院系, age, sex
c: cno课程号, cname课程名, cpno, credit学分
sc: sno, cno, score

相关子查询的查询过程

select sno,cno,score from sc as sc1
where score<(select max(score) from sc as sc2 where sc2.sno=sc1.sno)
如果直接执行“select max(score) from sc”,我们将会得到sc表中score最大的那一行记录,但我们把s1与s2做sno相等的等值连接,情况有所不同。sc1.sno在查询过程中是变化的,我们可以认为数据库遍历了sc,sc1.sno等于遍历中的某一项的值。因此,这段代码将显示除了sno对应的最高成绩外的所有成绩。

当我们用EXISTS的时候我们在干嘛

select count(*) from sc where exists(select * from c where c.cno=sc.cno and cname='数据库原理')
go
select count(*) from sc,c where (c.cno=sc.cno and cname='数据库原理')
这两种查询得到的结果是相同的,我们可以认为exists仅仅用于表达嵌套子查询,增加了查询的可读性。

T-SQL拷贝表

create table s1(
sno varchar(10) not null,sname varchar(20),dept varchar(20),age int,sex char(4))
go
insert into s1(sno,sname,dept,age,sex) select sno,sname,dept,age,sex from s
有时候需要拷贝一份表,但我在网上查到了很多写法并不符合t-sql的语法,上面是可以使用的版本。我只找到了先按照表的结构新建表然后插入所有数据的办法。在sqlserver2017中可以正常运行,如果不能用,可能需要在末尾加where 1=1。

利用default约束插入数据

insert into s1(sno,sname,dept,age) values(125,'name','dept',16)
go
select * from s1
一开始我用了insert into s1 values(125,'name','dept',16)没有成功,好在及时悔悟,数据库管理系统并不能智能补缺。。。我们应该老老实实写上所有要加的属性。ps:default只在insert into起作用。

外键约束

alter table sc add constraint fkey foreign key(cno) references c(cno)'注释:sc表中cno的取值仅限于c表中cno的取值
A属性的取值范围是B属性已有取值的集合。或者说A中不同元素的集合属于B中不同元素的集合。

SQL自定义函数(存储过程)的语法

create proc calculate @n int '注释:@n int 是传入的参数,可以没有;create proc proc_name必须要有
as
declare @sum int,@i int '注释:声明变量,sql中变量前都加@
set @i=0 '为变量赋值
set @sum=1
while @i<@n'支持循环语句
begin
set @i=@i+1
set @sum=@sum*@i
end
print @sum
'ps:除了用set为变量赋值,也可以用select @variable= column_name from table_name where 条件
执行函数只需要'exec proc_name'