-- 15.在课程表里添加一列:选课人数,设置触发器每门课如果有人选修了那么课程表里的选课人数相应修改,考虑批量插入选课记录的情况。 ALTERTABLE Course ADD Cselect INT; CREATEVIEW sc_select AS SELECT C.Cno,COUNT(*) AS'amount' FROM SC JOIN Course C on C.Cno = SC.Cno GROUPBY C.Cno; UPDATE Course SET Course.Cselect=(SELECT amount FROM sc_select WHERE Course.CNO=sc_select.Cno) WHERE Course.Cno IN (SELECT Cno FROM sc_select);
CREATETRIGGER t15 ON SC AFTER INSERTAS BEGIN DECLARE@cnoCHAR(4) DECLARE csr CURSOR FORSELECT Cno FROM inserted OPEN csr FETCH NEXT FROM csr INTO@cno WHILE @@FETCH_STATUS=0 BEGIN UPDATE Course SET Cselect=Cselect+1WHERE Cno=@cno FETCH NEXT FROM csr INTO@cno end CLOSE csr DEALLOCATE csr END;
--1. 用函数实现:求某个专业选修了某门课程的学生人数,并调用函数求出计算机系“数据库”课程的选课人数。 USE Student GO CREATEFUNCTION dbo.Sdept_select_amount(@sdeptVARCHAR(20),@cnameCHAR(40)) RETURNSINT BEGIN DECLARE@totINT SELECT@tot=COUNT(*) FROM Student JOIN dbo.SC S on Student.Sno = S.Sno JOIN Course C on C.Cno = S.Cno WHERE Cname=@cnameAND Sdept=@sdept RETURN@tot end GO
--2. 用内嵌表值函数实现:查询某个专业所有学生所选的每门课的平均成绩;调用该函数求出计算机系的所有课程的平均成绩。 CREATEFUNCTION dbo.Sdept_average_grade(@sdeptVARCHAR(20)) RETURNSTABLE AS RETURN ( SELECT C.Cno, C.Cname, AVG(Grade) AS'平均成绩' FROM Student JOIN dbo.SC S on Student.Sno = S.Sno JOIN Course C on C.Cno = S.Cno WHERE Sdept =@sdept GROUPBY C.Cno, C.Cname ) GO
SELECT*FROM Sdept_average_grade('CS')
3.多语句表值函数
RETURNS @表名 TABLE(…) +INSERT语句插入数据到临时表中 +RETURN
注意调用方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14
--3. 创建多语句表值函数,通过学号作为实参调用该函数,可显示该学生的姓名以及各门课的成绩和学分,调用该函数求出“200515002”的各门课成绩和学分。 CREATEFUNCTION dbo.Student_info(@snoCHAR(9)) RETURNS@Student_info TABLE(Sname CHAR(20),Cname CHAR(40),Grade SMALLINT,Ccredit SMALLINT) AS BEGIN INSERT@Student_info -- 奇怪的语法增加了 SELECT Sname,Cname,Grade,Ccredit FROM Student JOIN dbo.SC S on Student.Sno = S.Sno JOIN Course C on C.Cno = S.Cno WHERE Student.Sno=@sno RETURN end GO
ON UPDATE/DELETENO ACTION;--拒绝修改/删除 ON UPDATE/DELETE CASCADE;--级联修改/删除 ON UPDATE/DELETESETNULL;--设为空值 --对于参照完整性,除了应该定义外码,还应定义外码列是否允许为空 ON UPDATE/DELETESETDEFAULT;--设为默认值
INSERT INTO SC(Sno, Cno) VALUES (200515001,'2');--Grade可以为空,自动赋空值,sno和cno需要一一对应下面的数据
(2) 插入子查询结果
1 2 3 4 5
INSERT INTO SC(Sno, Cno) SELECT Student.Sno,Cno FROM Student JOIN SC S on Student.Sno = S.Sno--dgnb tab按到饱 WHERE Student.Sno='200515012';--乱写的不要当真,这个很显然不太符合现实
在执行插入语句时会检查所插入元组是否符合表上已经定义的完整性规则(实体、参照、用户定义)
5. UPDATE
UPDATE()-SET()-WHERE()
(1) 修改某一元组
(2) 修改多个元组
(3) 修改子查询结果中的语句
1 2 3
UPDATE SC SET Grade=Grade+1 WHERE Sno='200515000';
6. DELETE
DELETE-FROM()-WHERE()
(1) 删除某一元组
(2) 删除多个元组
(3) 删除子查询结果中的语句
1 2 3 4 5 6 7
--删除没有选课的学生 DELETE FROM Student WHERENOTEXISTS( SELECT* FROM sc WHERE Student.Sno=SC.Sno);
SELECT* SELECT Sno AS'学号' SELECT2021-Sage SELECTUPPER(Sdept) --专业代号全用大写字母显示 SELECTDISTINCT Sno SELECT TOP 10WITH TIES Grade --请配合ORDERBY SELECT TOP 10PERCENTWITH TIES Grade --选10% SELECT Sno,AVG(Grade) --请配合GROUPBY
(2) FROM…
1 2 3
FROM SC X FROM Student RIGHTJOIN SC S on Student.Sno = S.Sno FROM (SELECT Sno,AVG(Grade) FROM SC GROUPBY Sno) AS AVG_SC(AVGsno,AVGgrade) --派生表
(3) WHERE…
常用查询条件
谓词
比较
= > < >= <= !=
确定范围
BETWEEN AND, NOT BETWEEN AND
确定集合
IN, NOT IN
字符匹配
LIKE, NOT LIKE, ESCAPE
空值
IS NULL, IS NOT NULL
逻辑运算
AND, OR, NOT
子查询
IN, ALL, ANY, EXISTS, NOT EXISTS
1 2 3 4 5 6
WHERE Sno='200515001'AND Cno='1' WHERE Sname like'_s[123][^4]\_%'ESCAPE'\'' --表示\是换码字符 WHERE Sdept IN('CS','IS') WHERE Sdept IN (SELECT Sdept...) WHERE EXISTS(...) WHERE Sage>=ALL(SELECT Sage...)
(4) GROUP BY
聚集函数
COUNT([DISTINCT|ALL]<列名>)
SUM() AVG() MAX() MIN()
GROUP BY: 细化聚集函数的作用对象,聚集函数分别作用于每个组
HAVING短语作用于组,从中选择满足条件的组,(WHERE 作用于表和视图)
(5) ORDER BY
ORDER BY Grade ASC|DESC 升序、降序
(6) UNION INTERSECT EXPECT
集合查询,把两个表根据集合的条件连在一起(SELECT的内容要相同)
典型用法:查询选修1和2课程的学生集合
不能简单where-and,不可能cno同时等于两个值
1 2 3 4 5 6 7
SELECT Student.Sno,Student.Sname FROM Student JOIN SC S on Student.Sno = S.Sno WHERE Cno='1' INTERSECT SELECT Student.Sno,Student.Sname FROM Student JOIN SC S2 on Student.Sno = S2.Sno WHERE Cno='2';
8. 数据库安全性
GRANT权限-(DML权限加)ON表-TO用户/角色-WITH GRANT OPTION
DENY权限-ON表-TO用户/角色-CASCADE
REVOKE权限-ON表-FROM用户/角色
CREATE ROLE角色名-AUTHORIZATION所有者名
SQL的认证过程:连接权认证、访问权认证、操作权认证
连接权-登录账户(LOGIN)
1 2 3 4 5 6 7 8 9
CREATE LOGIN test WITH PASSWORD='123',default_database=Student ALTER LOGIN test WITH NAME=te ALTER LOGIN test WITH PASSWORD='456' DROP LOGIN test
exec sp_addlogin test,'123' exec sp_password '123','456',test --改密码 exec sp_droplogin test
访问权-数据库用户(USER)
CREATE USER – FOR LOGIN –
1 2 3 4
USE Student GO CREATEUSER test_user FOR LOGIN test
EXEC sp_adduser test,test_user
操作权-为数据库用户授予\拒绝\撤回xxx的权限
1 2 3 4 5 6 7 8 9 10 11 12 13 14
GRANTCREATETABLETO test_user
GRANTSELECT (Sno,Sname) -- sno,sname加括号 ON Student TO [public] WITHGRANT OPTION -- 可以再授予其他用户,不允许循环授权
DENY CREATETABLETO test_user-- 拒绝test_user创建表 DENY SELECT(Sno,Sname) ON Student TO [public] CASCADE-- 级联拒绝,所有其他拥有该用户授予权限的也拒绝