一、环境配置
- 安装SQL Server :进入官网下载 Developer 版本即可
- SQL Server Management Studio:SSMS 集成开发环境
二、数据库的创建与删除
1. 创建
IF EXISTS(SELECT * FROM sysdatabases WHERE NAME='xs') --检查在当前服务器系统中的所有数据里面是否有该数据库
DROP DATABASE xs --如果有删除该数据库
CREATE DATABASE xs --创建名为 xs 的数据库
ON PRIMARY( --配置数据库
NAME='xs_mdf.MDF', --主数据文件的逻辑名
FILENAME='D:\Program\SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\DB_Yx.MDF', --主数据文件存储位置
SIZE=10MB, --主数据文件的初始大小
FILEGROWTH=5%, --每次增容时增加的容量大小
MAXSIZE=40MB --最大容量 unlimited无限制
)LOG ON(
NAME='xs_log.LDF', --日志文件
FILENAME='D:\Program\SQL Server\MSSQL16.MSSQLSERVER\MSSQL\DATA\DB_Yx.LDF', --日志文件存储位置
SIZE=2MB, --日志文件初始大小
FILEGROWTH=1MB, --日志文件每次增加的容量大小
MAXSIZE=10MB
)
2. 使用
在进行数据定义、数据查询和数据更新等操作时要先确定使用的数据库
USE xs
3. 删除
DROP DATABASE xs
三、数据定义
1. 模式的定义与删除
CREATE SCHEMA "S-T" AUTHORIZATION yx; /* 创建模式,用户必须获得管理员权限*/
DROP SCHEMA "S-T"; /* SQL server 默认删除为 RESTRICT,不支持 CASCADE 删除*/
2. 基本表的定义、修改与删除
🎈定义
CREATE TABLE Student
(
Sno CHAR(9) PRIMARY KEY, /* PRIMARY KEY 设置主码*/
Sname CHAR(20) UNIQUE, /* UNIQUE 设置唯一值*/
Ssex CHAR(2),
Sage SMALLINT,
Sdept CHAR(20)
);
CREATE TABLE Course
(
Cno CHAR(4) PRIMARY KEY,
Cname CHAR(40) NOT NULL,
Cpno CHAR(4),
Ccredit SMALLINT,
FOREIGN KEY (Cpno) REFERENCES Course(Cno) /* FOREIGN KEY 设置外码,REFERENCES 设置参照表 */
);
CREATE TABLE SC
(
Sno CHAR(9),
Cno CHAR(4),
Grade SMALLINT,
PRIMARY KEY(Sno,Cno), /* PRIMARY KEY(,) 设置多个属性的主码 */
FOREIGN KEY (Sno) REFERENCES Student(Sno), /* FOREIGN KEY 设置外码,REFERENCES 设置参照表 */
FOREIGN KEY (Cno) REFERENCES Course(Cno) /* FOREIGN KEY 设置外码,REFERENCES 设置参照表 */
);
常用数据类型如下:
文章来源:https://www.toymoban.com/news/detail-742341.html
✨修改
ALTER TABLE Student ADD S_entrance DATE; /* 增加列并指明数据类型 */
ALTER TABLE Student ADD UNIQUE(S_entrance); /* 增加完整性约束 */
ALTER TABLE Student DROP CONSTRAINT UQ__Student__A4F042F0EF933D16; /* 删除完整性约束 */
ALTER TABLE Student DROP COLUMN S_entrance; /* 删除列(必须先删除约束) */
ALTER TABLE Student ALTER COLUMN Sno char(12); /* 修改列(必须先删除约束) */
📙删除
DROP TABLE SC; /* 默认删除为 RESTRICT(限制删),SQL server 不支持 CASCADE(级联删)关键字*/
DROP TABLE Course;
DROP TABLE Student;
3. 索引的建立与删除
CREATE UNIQUE INDEX Stusno ON Student(Sno); /* 按学号升序建唯一索引 */
CREATE UNIQUE INDEX Coucno ON Course(Cno); /* 按课程号升序建唯一索引 */
CREATE UNIQUE INDEX SCno ON SC(Sno ASC,Cno DESC); /* 按学号升序和课程号降序建唯一索引 */
DROP INDEX Stusno ON Student; /* 删除 Student 表的 Stusno 索引 */
四、数据查询
1. 单表查询
🎈按列查询
SELECT * /* 查询全部列 */
FROM Student;
SELECT 2023-Sage BirthDay /* 查询某表达式,并对查询结果起别名 */
FROM Student;
SELECT Sno,Sname,Sdept,2023-Sage BirthDay /* 查询若干列,顺序可以不同于表定义 */
FROM Student;
✨按行查询
SELECT * FROM Student; /* 查询全部行 */
SELECT DISTINCT Sno FROM Student; /* 查询 Sno ,并删除重复的元素 */
SELECT Sname /* 查询符合比较条件的行 */
FROM Student
WHERE Sage>18;
SELECT Sname /* 查询符合范围条件的行 */
FROM Student
WHERE Sage BETWEEN 18 AND 19;
SELECT Sname /* 查询符合集合条件的行 */
FROM Student
WHERE Sdept NOT IN('CS');
SELECT Sname /* 查询符合字符条件的行 */
FROM Student
WHERE Sname LIKE '_x%';
SELECT Sname
FROM Student
WHERE Sname LIKE 'DB\_test' ESCAPE '\'; /* 忽略转义字符 */
SELECT Sname /* 查询符合空值条件的行 */
FROM Student
WHERE Ssex IS NULL;
SELECT Sname /* 查询符合多重条件的行 */
FROM Student
WHERE Sdept IN('CS') AND Ssex IS NOT NULL;
📙 ORDER BY 子句(排序)
SELECT Sno,Grade
FROM SC
WHERE Cno='002'
ORDER BY Grade DESC; /* ASC为升序(默认),DESC为降序 */
🎯 GROUP BY 子句(分组)
SELECT COUNT(Sdept) SdeptCount
FROM Student
GROUP BY Sdept /* 按照 Sdept 分组查询统计COUNT */
HAVING COUNT(Sdept)>2; /* HAVING 作用于组,WHERE作用于基本表或视图 */
🏀聚集函数
- 计数
COUNT([DISTINCT|ALL] *)
COUNT([DISTINCT|ALL] <列名>)
- 计算总和
SUM([DISTINCT|ALL] <列名>)
- 计算平均值
AVG([DISTINCT|ALL] <列名>)
- 最大最小值
MAX([DISTINCT|ALL] <列名>)
MIN([DISTINCT|ALL] <列名>)
SELECT AVG(Grade) Average /* 计算选修 1 号课程的学生平均成绩 */
FROM SC
WHERE Cno='001';
2. 链接查询
🎈等值链接
SELECT Student.*,SC.*
FROM Student,SC
WHERE Student.Sno=SC.Sno;
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade /* 自然链接(去掉重复列) */
FROM Student,SC
WHERE Student.Sno=SC.Sno AND GRade=100; /* 可加限定条件 */
✨自身链接
SELECT First.Cno,Second.Cpno
FROM Course First,Course Second /* 给 Course 起两个别名 First、Second ,用于链接 */
WHERE First.Cpno=Second.Cno;
📙 外连接
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade /* 自然链接(去掉重复列) */
FROM Student LEFT OUTER JOIN SC ON (Student.Sno=SC.Sno); /* 左外连接 */
SELECT Student.Sno,Sname,Ssex,Sage,Sdept,Cno,Grade /* 自然链接(去掉重复列) */
FROM Student RIGHT OUTER JOIN SC ON (Student.Sno=SC.Sno); /* 右外连接 */
🎯 多表查询
SELECT Student.sno,Sname,Cname,Grade
FROM Student,Course,SC
WHERE Student.Sno=SC.Sno AND SC.Cno=Course.Cno;
3. 嵌套查询
🎈带 IN 的子查询
SELECT * /* 嵌套查询与 yx1 在一个系中的学生信息(不相关查询) */
FROM Student
WHERE Sdept IN
(SELECT Sdept
FROM Student
WHERE Sname='yx1');
SELECT S1.Sno,S1.Sname,S1.Ssex,S1.Sage,S1.Sdept /* 链接查询与 yx1 在一个系中的学生信息(不相关查询) */
FROM Student S1,Student S2
WHERE S1.Sdept=S2.Sdept AND S2.Sname='yx1';
✨带比较运算符的子查询
SELECT Sno,Cno /* 找出每个学生超过所选课程平均成绩的课程号(相关查询) */
FROM SC x
WHERE Grade >
(SELECT AVG(Grade)
FROM SC y
WHERE y.Sno=x.Sno);
📙 带 ANY、ALL 的子查询
- ANY:任意一个值
- ALL:所有值
SELECT Sname,Sage /* 查询非 CS 专业中比 CS 专业所有人都大的学生 */
FROM Student
WHERE Sage>ALL
(SELECT Sage
FROM Student
WHERE Sdept='CS')
AND Sdept != 'CS'; /* 父查询的条件 */
🎯 带 EXISTS 的子查询
SELECT Sname /* 查找选修1号课程的所有学生 */
FROM Student
WHERE EXISTS /* 存在返回true,否则返回false */
(SELECT *
FROM SC
WHERE Sno=Student.Sno AND Cno='001');
4. 集合查询
🎈交操作 INTERSECT
SELECT *
FROM Student
WHERE Sdept='CS'
INTERSECT
SELECT *
FROM Student
WHERE Sage<=19;
✨并操作 UNION
SELECT *
FROM Student
WHERE Sdept='CS'
UNION
SELECT *
FROM Student
WHERE Sage>=19;
📙 差操作 EXCEPT
SELECT *
FROM Student
WHERE Sdept='CS'
EXCEPT
SELECT *
FROM Student
WHERE Sage<=19;
5. 基于派生表的查询
SELECT Sno,Cno /* 找出每个学生超过所选课程平均成绩的课程号 */
FROM SC,(SELECT Sno,Avg(Grade) FROM SC GROUP BY Sno) AS Avg_sc(avg_sno,avg_grade)
WHERE SC.Sno = Avg_sc.avg_sno AND SC.Grade >= Avg_sc.avg_grade;
SELECT Sname /* 查询所有选修了1号课程的学生 */
FROM Student,(SELECT Sno FROM SC WHERE Cno='001') AS SC1 /* AS和属性列可以省略(默认为SELECT后面的顺序),但必须为派生关系指定别名 */
WHERE Student.Sno = SC1.Sno;
五、数据更新
1. 插入数据
🎈插入元组
INSERT INTO Student(Sno,Sname,Ssex,Sage,Sdept) VALUES
('202107020326','yx1','男',18,'CS'),
('202107020327','yx2','男',19,'CS'),
('202107020328','yx3','男',20,'CS'),
('202107020329','yx4','女',21,'CS');
('202107020329','xing1','女',22,'MA');
('202107020329','DB_test','男',23,'MA');
INSERT INTO Course(Cno,Cname,Cpno,Ccredit) VALUES
('001','高数','无',6),
('002','C语言','无',3),
('003','数据结构','002',3),
('004','数据库','003',3);
INSERT INTO SC(Sno,Cno,Grade) VALUES
('202107020326','001',100),
('202107020326','002',100),
('202107020326','003',80),
('202107020327','001',90),
('202107020328','002',90);
✨插入子查询结果
CREATE TABLE Dept_age /* 建立新表,存储每个系学生的平均年龄 */
(
Sdept CHAR(15),
Avg_age SMALLINT
);
INSERT INTO Dept_age(Sdept,Avg_age) /* 查新每个系中学生的平均年龄,并插入新表中 */
SELECT Sdept,AVG(Sage)
FROM Student
GROUP BY Sdept;
2. 修改数据
🎈修改元组
UPDATE Student /* 将名为 DB_test 的学号修改为 202107020331 */
SET Sno='202107020331'
WHERE Sname='DB_test';
UPDATE Student /* 给所有学生的年龄加一 */
SET Sage=Sage+1;
✨修改子查询结果
UPDATE SC /* 将计算机系学生成绩置零 */
SET Grade=0
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS');
3. 删除数据
🎈插入元组
DELETE /* 删除名为 yx4 的学生 */
FROM Student
WHERE Sname='yx4';
DELETE /* 删除所有学生的选课记录 */
FROM SC;
✨插入子查询结果
DELETE /* 删除所有计算机系学生的选课记录 */
FROM SC
WHERE Sno IN
(SELECT Sno
FROM Student
WHERE Sdept='CS');
六、视图
1. 视图的作用及特点
🎈作用
- 视图能够简化用户的操作
- 视图使用户能以多种角度看待同一数据
- 视图对重构数据库提供了一定程度的逻辑独立性
- 视图能够对机密数据提供安全保护
- 适当的利用视图可以更清晰的表达查询
✨特点
- 虚表,是从一个或几个基本表(或视图)导出的表
- 只存放视图的定义,不存放视图对应的数据
- 基表中的数据发生变化,从视图中查询出的数据也随之改变
2.定义视图
🎈建立视图
CREATE VIEW IS_Student /* 建立信息系学生的视图,可以省略视图的列名,默认为 SELECT 语句后的顺序 */
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION; /* WITH CHECK OPTION 默认以后的插入、修改和删除操作加上 Sdept='IS' 条件 */
CREATE VIEW IS_S1(Sno,Sname,Grade) /* 建立信息系选修了1号课程的学生的视图 */
AS
SELECT Student.Sno,Student.Sname,Grade
FROM Student,SC /* 视图可以建立在多个表上 */
WHERE Sdept='IS' AND Student.Sno = SC.Sno AND SC.Cno = '1'
CREATE VIEW IS_S2 /* 建立信息系选修了1号课程且成绩在90分以上的学生的视图 */
AS
SELECT Sno,Sname,Grade
FROM IS_S1 /* 视图可以建立在其他视图上 */
WHERE GRADE >= 90;
CREATE VIEW BT_S(Sno,Sname,Sbirth) /* 建立带虚拟列(Sbirth)的视图 */
AS
SELECT Sno,Sname,2023-Sage
FROM Student;
CREATE VIEW S_G(Sno,Gavg) /* 建立带有聚集函数的视图 */
AS
SELECT Sno,AVG(Grade)
FROM SC
GROUP BY Sno;
✨删除视图
DROP VIEW IS_S1 CASCADE; /* 级联删除,SQL Server 不支持 CASCADE 关键字*/
DROP VIEW IS_S2; /* 普通删除 */
3.查询视图
- 视图建立后,用户就可以像对基本表一样对视图进行查询了
- 基于视图的查询会基于视图的定义先进行视图消解(优化语句)
- 目前大多数关系数据库都可以正确转换对行列子集视图的查询,对于非行列子集视图的查询只能对基本表直接操作
- 查询视图的结果会永久保留在数据字典中,而基于派生表的查询是临时的
--定义视图
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
--查询视图
SELECT Sno,Sage
FROM IS_Student
WHERE Sage<20;
--视图消解后(结合视图定义和用户查询的条件去优化语句)
SELECT Sno,Sage
FROM IS_Student
WHERE Sdept = 'IS' AND Sage<20;
4.更新视图
- 对视图的更新最终会转化为对基本表的更新,所以并不是所有的视图都可以更新
🎈插入数据
--视图定义
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
--原语句(对视图)
INSERT INTO IS_Student VALUES
('202107020326','yx',18);
--更新后语句(对基本表)
INSERT INTO Student(Sno,Sname,Sage,Sdept) VALUES
('202107020326','yx',18);
✨修改数据
--视图定义
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
--原语句(对视图)
UPDATE IS_Student
SET Sname='yx1'
WHERE Sno='202107020326';
--更新后语句(对基本表)
UPDATE IS_Student
SET Sname='yx1'
WHERE Sno='202107020326' AND Sdept='IS';
📙 删除数据
--视图定义
CREATE VIEW IS_Student
AS
SELECT Sno,Sname,Sage
FROM Student
WHERE Sdept='IS'
WITH CHECK OPTION;
--原语句(对视图)
DELETE
FROM IS_Student
WHERE Sno='202107020326'
--更新后语句(对基本表)
DELETE
FROM IS_Student
WHERE Sno='202107020326' AND Sdept='IS';
六、数据库安全性
1. 授权
🎈授予
GRANT SELECT /* 授予用户 yx 查询表 Student 的权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
TO yx;
GRANT ALL PRIVILEGES /* 把表 Student 的所有操作权限授予所有用户 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
TO PUBLIC;
WITH GRANT OPTION; /* 允许循环授权 */
✨收回
REVOKE UPDATE(Sno) /* 收回用户 yx 修改学生学号的权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
FROM yx;
REVOKE INSERT /* 收回所有用户对表 Student 的查询权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
FROM PUBLIC;
REVOKE INSERT /* 收回用户 yx 的插入权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
FROM yx CASCADE; /* 级联收回 */
2. 角色管理
🎈创建
CREATE ROLE SeniorProgrammer; /* 创建高级程序猿角色 */
✨授权
GRANT SELECT /* 授予角色 SeniorProgrammer 查询表 Student 的权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
TO SeniorProgrammer;
REVOKE SELECT /* 收回角色 SeniorProgrammer 查询表 Student 的权限 */
ON TABLE Student /* SQL Server 中使用要删除该条语句中的 TABLE 关键字 */
FROM SeniorProgrammer CASCADE; /* 级联收回 */
-- SQL Server 不支持,会出现语法错误
GRANT SeniorProgrammer /* 将高级程序员的权限授予低级程序员 */
TO JuniorProgrammer
WITH ADMIN OPTION; /* 允许循环授权 */
3. 审计
- 审计日志(Audit Log):将用户对数据库的所有操作记录在上面
- DBA可以利用审计日志找出非法存取数据的人、时间和内容,C2以上安全级别的DBMS必须具有
- 用户级审计
- 针对自己创建的数据库表或视图进行审计 ;
- 记录所有用户对这些表或视图的一切成功、不成功的访问要求以及各种类型的SQL操作 ;
- 系统级审计
- DBA设置
- 监测成功或失败的登录要求
- 监测 GRANT 和 REVOKE 操作以及其他数据库级权限下的操作
🎈设置与取消
-- SQL Server 不支持,会出现语法错误
AUDIT ALTER,UPDATE /* 对修改 SC 表结构或修改 SC 表数据的操作进行审计 */
ON SC;
NOAUDIT ALTER,UPDATE /* 取消 SC 表的一切审计 */
ON SC;
七、数据库完整性
1. 实体完整性
🎈定义
--列级定义
CREATE TABLE Student
(Sno CHAR(9) PRIMARY KEY, /* 单属性列级、表级都可以定义 */
Ssex CHAR(2),
Sdept CHAR(20),
);
--表级定义
CREATE TABLE SC
(Sno CHAR(9) NOT NULL,
Cno CHAR(4) NOT NULL,
PRIMARY KEY(Sno,Cno), /* 多属性只能表级定义 */
);
✨违约处理
- 检查主码值是否唯一,如果不唯一则拒绝插入或修改
- 检查主码的各个属性是否为空,只要有一个为空就拒绝插入或修改
2. 参照完整性
🎈定义
CREATE TABLE SC /* FOREIGN KEY 定义外码,REFERENCES 定义参照主码 */
(Sno CHAR(9) NOT NULL,
FOREIGN KEY(Sno) REFERENCES Student(Sno),
);
✨违约处理
- 拒绝(NO ACTION)执行,默认策略
- 级联(CASCADE)操作
- 设置为空值(SET-NULL),对于参照完整性,除了应该定义外码,还应定义外码列是否允许空值
3. 用户定义完整性
- 列值非空
NOT NULL
- 列值唯一
UNIQUE
- 检查列值是否满足某条件表达式
CHECK 表达式
🎈定义
CREATE TABLE Student
(Sno CHAR(9) UNIQUE NOT NULL, /* 属性上的约束条件 */
Sname CHAR(8) NOT NULL,
Ssex CHAR(2) CHECK (Ssex IN ('男','女')),
CHECK (Ssex='女' OR Sname NOT LIKE 'MS%'), /* 元组上的约束条件 */
);
4. 完整性约束命名子句
🎈定义
CREATE TABLE Student /* 建立约束 C1 要求学号在(90000-99999)之间,约束 C2 要求姓名不能取空 */
(Sno NUMERIC(6) UNIQUE CONSTRAINT C1 CHECK(Sno BETWEEN 90000 AND 99999),
Sname CHAR(20) CONSTRAINT C2 NOT NULL
);
✨修改
ALTER TABLE Student DROP CONSTRAINT C1; /* 先删后加,即为修改 */
ALTER TABLE Student ADD CONSTRAINT C1 CHECK(Sno>0);
5. 触发器
- 触发器(Trigger)是用户定义在关系表上的一类由事件驱动的特殊过程由服务器自动激活
- 可以进行更为复杂的检查和操作,具有更精细和更强大的数据控制能力
🎈定义
文章来源地址https://www.toymoban.com/news/detail-742341.html
✨语句
CREATE TRIGGER Insert_Or_Update_Sal
BEFORE INSERT OR UPDATE ON Teacher /* 触发事件是插入或更新操作 */
REFERENCING NEW row AS newTuple /* 将触发事件后命名为newTuple */
FOR EACH ROW /* 行级触发器 */
BEGIN /* 定义触发动作体,这是一个 PL/SQL 过程块 */
IF (newTuple.Job='教授') AND (newTuple.Sal<4000)
THEN newTuple.Sal :=4000;
END IF;
END;
DROP TRIGGER Insert_Or_Update_Sal ON Teacher; /* 从表 Teacher 中删除触发器 Insert_Or_Update_Sal */
到了这里,关于【SQL】SQL Server基础语法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!