[TOC]

1章

l 数据库由一些持久的相互关联的数据的集合组成,并以一定的组织形式存放在计算机的存储介质中。

l 数据、数据库、数据库管理系统操作数据库的应用程序,加上支撑它们的硬件平台软件平台和与数据库有关的人员一起构成了一个完整的数据库系统

l 数据模型:层次、网状、关系

l SQL语言的功能包括数据查询、数据操纵、数据定义和数据控制4部分。

l 实体之间的联系主要有:一对一、一对多、多对多

l SQL Server 2008有两个选项:Windows身份验证模式混合模式

2章

| 用户可以给出两种对象名,即完全限定名部分限定名详见

  • 完全限定名。在SQL Server 2008中,完全限定名是对象的全名,包括4个部分:服务器名、数据库名、数据库架构名和对象名。
  • 对象全名的4个部分中的前3个部分均可以省略,当省略中间的部分时,圆点符“.”不可省略。

l SQL Server 2008中有两个主要的数据存储单位:页和区。页是用于数据存储的最基本单位区是用于管理空间的基本单位详见

1
2
3
4
5
SQL Server 2008中有两个主要的数据存储单位:页和区。

页是用于数据存储的最基本单位。每个页的大小是8 KB。每页的开头是96 B的标头,用于存储有关页的系统信息。紧接着标头存放的是数据行,数据行按顺序排列。数据库表中的每一行数据都不能跨页存储,即表中的每一行数据字节数不能超过8192。页的末尾是行偏移表,页中的每一行在偏移表中都有一个对应的条目。每个条目记录着对应行的第一个字节与页首部的距离。

区是用于管理空间的基本单位。每8个连接的页组成一个区,大小为64 KB,即每1 MB的数据库就有16个区。区用于控制表和索引的存储。

l SQL Server 2008所使用的文件包括以下三类文件。详见

  • (1)主数据文件。其默认扩展名为.mdf。

  • (2)辅助数据文件。默认扩展名为.ndf。辅助文件是可选的,也可以不使用辅助文件。一般当数据库很大时,有可能需要创建多个辅助文件。而当数据库较小时,则只需要创建主文件而不需要创建辅助文件。

  • (3)日志文件。扩展名为.ldf

  • SQL Server 2008所使用的文件包括以下三类文件。
    
    (1)主数据文件。主数据文件简称主文件,正如其名字所示,该文件是数据库的关键文件,包含了数据库的启动信息,并且存储数据。每个数据库必须有且仅能有一个主文件,其默认扩展名为.mdf。可直接拷贝
    
    (2)辅助数据文件。辅助数据文件简称辅(助)文件,用于存储未包括在主文件内的其他数据。辅助文件的默认扩展名为.ndf。辅助文件是可选的,根据具体情况,可以创建多个辅助文件,也可以不使用辅助文件。一般当数据库很大时,有可能需要创建多个辅助文件。而当数据库较小时,则只需要创建主文件而不需要创建辅助文件。
    
    (3)日志文件。日志文件用于保存恢复数据库所需的事务日志信息。每个数据库至少有一个日志文件,也可以有多个,日志文件的扩展名为.ldf。日志文件的存储与数据文件不同,它包含一系列记录,这些记录的存储不以页为存储单位。
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30

    l 在安装SQL Server 2008时,系统将创建4个可见的系统数据库:master、model、msdb和tempdb。[详细](https://zlogs.net/note/learn-sql/page/11249.html?h=tempdb)

    + (1)master数据库包含了**SQL Server 2008的登录账号、系统配置、数据库位置及数据库错误信息**等,控制用户数据库和SQL Server的运行。
    + (2)model数据库为**新创建的数据库提供模板**。
    + (3)msdb数据库为“SQL Server代理”**调度信息和作业记录**提供存储空间。
    + (4)tempdb数据库为**临时表和临时存储过程**提供存储空间,所有与系统连接的用户的临时表和临时存储过程都存储于该数据库中。

    l 在SQL Server 2008中,创建数据库快照也使用CREATE DATABASE命令.[详细](https://zlogs.net/note/learn-sql/page/11046.html?h=%E5%BF%AB%E7%85%A7)

    ```sql
    (5)恢复到数据库快照。可以使用RESTORE语句将数据库恢复到创建数据库快照时的状态。此时恢复的数据库会覆盖原来的数据库。
    语法格式:
    RESTORE DATABASE { database_name | @database_name_var }
    FROM DATABASE_SNAPSHOT = database_snapshot_name
    【例8.10】 创建PXSCJ数据库的快照,并将数据库恢复到创建该快照时的状态。
    首先创建PXSCJ数据库的快照:
    CREATE DATABASE PXSCJ_1
    ON
    (
    NAME=PXSCJ,
    FILENAME='E:\data\PXSCJ_1.mdf'
    )
    AS SNAPSHOT OF PXSCJ
    GO
    接着对数据库做一些修改,以确定数据库是否恢复。恢复数据库的语句如下:
    USE master
    GO
    RESTORE DATABASE PXSCJ
    FROM DATABASE_SNAPSHOT='PXSCJ_1'

l 视图与表的区别:

  • 由于视图本身并不存储实际数据,因此也可以称之为虚表。视图中的数据来自定义视图的查询所引用的基本表,并在引用时动态生成数据。当基本表中的数据发生变化时,从视图中查询出来的数据也随之改变。视图一经定义,就可以像基本表一样被查询、修改、删除和更新了。

课件例2.5、2.7

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
【例2.5】  创建一个名为TEST1的数据库,其初始大小为5 MB,最大大小为50 MB,允许数据库自动增长,增长方式是按10%比例增长。日志文件初始为2 MB,最大可增长到5 MB,按1 MB增长。数据文件和日志文件的存放位置为SQL Server的数据库目录“C:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\ MSSQL\DATA”。假设SQL Server服务已启动,并以系统管理员身份登录计算机。
在“SQL Server Management Studio”窗口中单击“新建查询”按钮新建一个查询窗口,如图2.12所示。


在“查询分析器”窗口中输入如下T-SQL语句:
CREATE DATABASE TEST1
ON
(
NAME= 'TEST1_DATA',
FILENAME='C:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\MSSQL\DATA\TEST1.mdf',
SIZE=5 MB,
MAXSIZE=50 MB,
FILEGROWTH=10%
)
LOG ON
(
NAME='TEST1_log',
FILENAME='C:\Program Files\Microsoft SQL Server\MSSQL10.SQL2008\MSSQL\DATA\TEST1.ldf',
SIZE=2 MB,
MAXSIZE=5 MB,
FILEGROWTH=1 MB
);

通过数据库属性对话框可以看到,新建立TEST1数据库的各项属性完全符合预定要求。
【例2.6】 创建一个名为TEST2的数据库,它有两个数据文件,其中,主数据文件为20 MB,最大大小不限,按10%增长。 1个辅数据文件为20 MB,最大大小不限,按10%增长;有1个日志文件,大小为50 MB,最大大小为100 MB,按10 MB增长。
在查询分析器中输入如下T-SQL语句并执行.

CREATE DATABASE TEST2
ON
PRIMARY
(
NAME = 'TEST2_data1',
FILENAME = 'D:\data\test2_data1.mdf',
SIZE = 20 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10%
),
(
NAME = 'TEST2_data2',
FILENAME = 'D:\data\test2_data2.ndf',
SIZE = 20 MB,
MAXSIZE = UNLIMITED,
FILEGROWTH = 10%
)
LOG ON
(
NAME = 'TEST2_log1',
FILENAME = 'D:\data\test2_log1.ldf',
SIZE = 50 MB,
MAXSIZE = 100 MB,
FILEGROWTH = 10 MB
);
【例2.7】 创建一个具有2个文件组的数据库TEST3。要求:
1)主文件组包括文件TEST3_dat1,文件初始大小为20 MB,最大为60 MB,按5 MB增长;
2)有1个文件组名为TEST3Group1,包括文件TEST3_dat2,文件初始大小为10 MB,最大为30 MB,按10%增长。
CREATE DATABASE TEST3
ON
PRIMARY
(
NAME = 'TEST3_dat1',
FILENAME = 'D:\data\TEST3_dat1.mdf',
SIZE = 20 MB,
MAXSIZE = 60 MB,
FILEGROWTH = 5 MB
),
FILEGROUP TEST3Group1
(
NAME = 'TEST3_dat2',
FILENAME = 'D:\data\TEST3_dat2.ndf',
SIZE = 10 MB,
MAXSIZE = 30 MB,
FILEGROWTH = 10%
)

3章

l varchar、nvarchar、varbinary这三种数据类型可以使用MAX关键字

如varchar(MAX)、nvarchar(MAX)、varbinary(MAX),

加了MAX关键字的这几种数据类型最多可存放$2^{31}-1$字节的数据,分别用来替换text、ntext和image数据类型。详见

varchar(MAX)小于varchar时等于varchar,当大于时,会自动扩充到系统允许范围,如fat32最大允许单文件4GB,MSSQL想用他取代text,因为text有其他操作无法实现如=等,其他同理,数据库迁移时,在MariaDB中获得类似存储大小的唯一方法是使用LONGBLOB数据类型。

参考

l 当用户使用界面方式修改表的结构(如添加列、修改列的数据类型等)时,必须删除原来的表,再重新创建新表才能完成表的更改。当表中有了记录后,建议不要轻易改变表结构,特别不要改变数据类型,以免产生错误。具有以下特性的列不能修改:详见

  • 数据类型为timestamp的列;
  • 计算列;
  • 全局标识符列;
  • 用于索引的列(但当用于索引的列为varchar、nvarchar或varbinary数据类型时,可以增加列的长度);
  • 用于由CREATE STATISTICS生成统计的列,如需修改这样的列,则必须先用DROP STATISTICS语句删除统计;
  • 用于主键或外键约束的列;
  • 用于CHECK或UNIQUE约束的列;
  • 关联有默认值的列。

时间戳+全局标识符+有约束(主外键、默认、非空、check、unique)+计算列

|当改变列的数据类型时,要求满足下列条件:

  • 原数据类型必须能够转换为新数据类型。
  • 新数据类型不能为timestamp类型。
  • 如果被修改列属性中有“标识规范”属性,则新数据类型必须是有效的“标识规范”数据类型。

l 使用TRUNCATE TABLE语句删除表数据 详细

1
2
3
4
5
6
7
8
9
使用TRUNCATE TABLE语句删除表数据

使用TRUNCATE TABLE语句将删除指定表中的所有数据,因此也称为清除表数据语句。

语法格式:
TRUNCATE TABLE tb_name
使用TRUNCATE TABLE语句删除了指定表中的所有行,但表的结构及其列、约束、索引等保持不变,而新行标识所用的计数值重置为该列的初始值。如果要保留标识计数值,则要使用DELETE语句。

TRUNCATE TABLE在功能上与不带WHERE子句的DELETE语句相同,二者均删除表中的全部行; 但TRUNCATE TABLEDELETE速度快,且使用的系统和事务日志资源少。 DELETE语句每次删除一行,并在事务日志中为所删除的每一行记录一项。 而TRUNCATE TABLE通过释放存储表数据所用的数据页来删除数据,并且只在事务日志中记录页的释放。

l 讨论数据类型时,使用了精度、小数位数和长度3个概念,它们的含义如下。详细

  • 精度:指数值数据中所存储的十进制数据的总位数。
  • 小数位数:指数值数据中小数点右边可以有的数字位数的最大值。例如,数值数据3890.587的精度是7,小数位数是3。
  • 长度:指存储数据所使用的字节数。详细

| 使用T-SQL语句创建分区表 详细

  • (1)创建分区函数
  • (2)创建分区方案
  • (3)使用分区方案创建分区表。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
1.使用T-SQL语句创建分区表

1)创建分区函数。创建分区函数使用CREATE PARTITION FUNCTION命令,语法格式如下。


CREATE PARTITION FUNCTION partition_function_name ( input_parameter_type )
AS RANGE [ LEFT | RIGHT ] =在哪一侧
FOR VALUES ( [ boundary_value [ ,...n ] ] )
[ ; ]


【例3.7】 对int类型的列创建一个名为NumberPF的分区函数,该函数把int类型的列中数据分成5个区。分为小于或等于50的区、大于50且小于或等于500的区、大于500且小于或等于1000的区、大于1000且小于或等于2000的区、大于2000的区。

CREATE PARTITION FUNCTION NumberPF(int)
AS RANGE LEFT FOR VALUES(50,500,1000,2000)
GO


2)创建分区方案。分区函数创建完后可以使用CREATE PARTITION SCHEME命令创建分区方案,由于在创建分区方案时需要根据分区函数的参数定义映射分区的文件组。所以需要有文件组来容纳分区数,文件组可以由一个或多个文件构成,而每个分区必须映射到一个文件组。一个文件组可以由多个分区使用。在一般情况下,文件组数最好与分区数相同,并且这些文件组通常位于不同的磁盘上。一个分区方案只可以使用一个分区函数,而一个分区函数可以用于多个分区方案中。

CREATE PARTITION SCHEME命令的语法格式如下。


CREATE PARTITION SCHEME partition_scheme_name
AS PARTITION partition_function_name
[ ALL ] TO ( { file_group_name | [ PRIMARY ] } [ ,...n ] )
[ ; ]


【例3.8】 假设文件组FGroup1、FGroup2、FGroup3、FGroup4、FGroup5已经在数据库PXSCJ中存在。根据例3.7中定义的分区函数创建一个分区方案,将分区函数中的5个分区分别存放在这5个文件组中。

CREATE PARTITION SCHEME NumberPS
AS PARTITION NumberPF
TO(FGroup1, FGroup2, FGroup3, FGroup4, FGroup5)
GO

3)使用分区方案创建分区表。分区函数和分区方案创建以后就可以创建分区表了。创建分区表使用CREATE TABLE语句,只要在ON关键字后指定分区方案和分区列即可。

【例3.9】 在数据库PXSCJ中创建分区表,表中包含“编号”(值可以是15000)、“名称”两列,要求使用例3.8中的分区方案。
USE PXSCJ
CREATE TABLE sample
(
编号 int NOT NULL PRIMARY KEY,
名称 char(8) NOT NULL
)
ON NumberPS(编号)
GO

| 新增加了一个MERGE语句:详细

例3.22创建表a,要求表中数据与XSB表同步。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
【例3.22】  创建表a,要求表中数据与XSB表同步。
创建学生表的语句如下。
USE PXSCJ
GO
CREATE TABLE a
(
学号 char(6) NOT NULL PRIMARY KEY,
姓名 char(8) NOT NULL,
性别 bit NULL DEFAULT 1,
出生时间 date NULL,
专业 char(12) NULL,
总学分 int NULL,
备注 varchar(500) NULL
)

进行信息同步使用如下语句。
MERGE INTO a
USING XSB ON a.学号=XSB.学号
WHEN MATCHED
THEN UPDATE SET a.姓名=XSB.姓名,a.性别=XSB.性别,a.出生时间=XSB.出生时间,
a.专业=XSB.专业,a.总学分=XSB.总学分,a.备注=XSB.备注
WHEN NOT MATCHED
THEN INSERT VALUES(XSB.学号,XSB.姓名,XSB.性别,XSB.出生时间,XSB.专业,
XSB.总学分,XSB.备注)
WHEN NOT MATCHED BY SOURCE
THEN DELETE;

表的创建

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
【例3.5】  设已经创建了数据库PXSCJ,现在该数据库中需创建学生情况表XSB,该表的结构见表3.3。创建表XSB的T-SQL语句如下:
USE PXSCJ
GO
CREATE TABLE XSB
(
学号 char(6) NOT NULL PRIMARY KEY,
姓名 char(8) NOT NULL,
性别 bit NULL DEFAULT 1,
出生时间 date NULL,
专业 char(12) NULL,
总学分 int NULL,
备注 varchar(500) NULL
)

【例3.6】 创建一个带计算列的表,表中包含课程的课程号、总成绩和学习该课程的人数,以及课程的平均成绩。
CREATE TABLE PJCJ
(
课程号 char(3) PRIMARY KEY,
总成绩 real NOT NULL,
人数 int NOT NULL,
平均成绩 AS 总成绩/人数 PERSISTED
)

表数据操作

https://zlogs.net/note/learn-sql/page/11263.html

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
【例3.14】  假设上表XSB中专业的默认值为“计算机”,备注默认值为NULL,则插入上例数据可以使用以下命令:
INSERT INTO XSB (学号, 姓名, 性别, 出生时间, 总学分)
VALUES('081101', '王林', 1, '1990-02-10', 50)
下列命令效果相同:
INSERT INTO XSB
VALUES('081101', '王林', 1, '1990-02-10', DEFAULT,50, NULL);

【例3.15】 一次向XSB表中插入两行数据:('091101', '王海', 1, '1991-05-10', '软件工程', 50, NULL)和('091102', '李娜', 0, '1991-04-12', '软件工程', 52, NULL)。
INSERT INTO XSB VALUES
('091101', '王海', 1, '1991-05-10', '软件工程', 50, NULL), ('091102', '李娜', 0, '1991-04-12', '软件工程', 52, NULL)

【例3.16】 向学生管理系统涉及的其他表中插入数据。
向KCB表加入数据的T-SQL语句示例如下:
INSERT INTO KCB VALUES('101','计算机基础',1,80,5)
向CJB表加入数据的T-SQL语句示例如下:
INSERT INTO CJB VALUES('081101',101,80)

【例3.17】 从表XSB中生成计算机专业的学生表,包括学号、姓名、专业,要求新表中的数据为结果集中前5行。
用CREATE语句建立表XSB1:
USE PXSCJ
GO
CREATE TABLE XSB1
( num char(6) NOT NULL PRIMARY KEY,
name char(8) NOT NULL,
speiality char(10) NULL
)
用INSERT语句向XSB1表中插入数据:
INSERT TOP(5) INTO XSB1
SELECT 学号, 姓名, 专业
FROM XSB
WHERE 专业= '计算机'
1
2
3
4
5
6
7
8
9
10
11
12
【例3.18】  将PXSCJ数据库的XSB表中总学分大于52的行删除,使用如下语句:
USE PXSCJ
GO
DELETE
FROM XSB
WHERE 总学分>52
GO
【例3.19】 将PXSCJ数据库的XSB表中备注为空的行删除(实际不做操作):
DELETE FROM XSB
WHERE 备注 IS NULL
删除PXSCJ数据库的XSB表中的所有行(实际不做操作):
DELETE XSB
1
2
3
4
5
6
7
8
9
10
11
12
13
【例3.21】  将XSB表(数据以附录A中XSB表的样本数据为准)中所有学生的总学分都增加10。将姓名为“罗林琳”的同学的专业改为“软件工程”,备注改为“提前修完学分”,学号改为081261。
USE PXSCJ
GO
UPDATE XSB
SET 总学分 = 总学分+10
GO
UPDATE XSB
SET 专业 = '软件工程',
备注 = '提前修完学分',
学号 = '081261'
WHERE 姓名 = '罗林琳'
GO
SELECT * FROM XSB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
【例4.4】  查询XSB表中计算机系同学的学号、姓名和总学分,结果中各列的标题分别指定为number、name和mark。
USE PXSCJ
GO
SELECT 学号 AS number, 姓名 AS name, 总学分 AS mark
FROM XSB
WHERE 专业= '计算机'

更改查询结果中的列标题也可以使用column_alias=expression的形式。例如,
SELECT number= 学号, name = 姓名, mark = 总学分
FROM XSB
WHERE 专业= '计算机'
该语句的执行结果与上例的结果完全相同。
当自定义的列标题中含有空格时,必须使用引号将标题括起来。例如,
SELECT 'Student number' = 学号,姓名 AS 'Student name', mark = 总学分
FROM XSB
WHERE 专业= '计算机'
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
【例4.27】  查找选修了课程号为206的课程的学生情况。
在“查询分析器”窗口中输入并执行如下查询脚本:
USE PXSCJ
GO
SELECT *
FROM XSB
WHERE 学号 IN
( SELECT 学号
FROM CJB
WHERE 课程号 = '206')
在执行包含子查询的SELECT语句时,系统先执行子查询,产生一个结果表,再执行查询。本例中,先执行上面括号里面的子查询:
SELECT 学号FROM CJB WHERE 课程名 = '206'


【例4.28】 查找未选修离散数学的学生情况。
SELECT *
FROM XSB
WHERE 学号 NOT IN (
SELECT 学号
FROM CJB
WHERE 课程号 IN (
SELECT 课程号
FROM KCB
WHERE 课程名 = '离散数学'
)
)

【例4.29】 查找选修了离散数学的学生学号。
SELECT 学号
FROM CJB
/* 一对一用=,多个值用in等*/
WHERE 课程号 =
(
SELECT 课程号
FROM KCB
WHERE 课程名 ='离散数学'
);
【例4.30】 查找比所有计算机系的学生年龄都大的学生。
SELECT *
FROM XSB
WHERE 出生时间 < ALL
(
SELECT 出生时间
FROM XSB
WHERE 专业= '计算机'
)

【例4.32】 查找选修206号课程的学生姓名。
SELECT 姓名
FROM XSB
WHERE EXISTS
(
SELECT *
FROM CJB
WHERE 学号 = XSB.学号 AND 课程号 = '206'
)

其处理过程如下:
首先查找外层查询中XSB表的第一行,根据该行的学号列值处理内层查询,若结果不为空,则WHERE条件为真,就把该行的姓名值取出作为结果集的一行;然后再找XSB表的第23…行,重复上述处理过程直到XSB表的所有行都查找完为止。


【例4.33】 查找选修了全部课程的同学的姓名。
SELECT 姓名
FROM XSB
WHERE NOT EXISTS
(
SELECT *
FROM KCB
WHERE NOT EXISTS
(
SELECT *
FROM CJB
WHERE 学号=XSB.学号 AND 课程号=KCB.课程号
)
)
1
2
3
4
5
【例4.61】  生成一个结果集,分别根据专业和性别对人数进行聚合。
SELECT 专业, 性别, COUNT(*) AS '人数'
FROM XSB
GROUP BY GROUPING SETS(专业,性别)
执行结果如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
与WHERE子句的查询条件类似,不过HAVING子句中可以使用聚合函数,而WHERE子句中不可以。

【例4.63】 查找选修课程超过2门且成绩都在80分以上的学生的学号。
SELECT 学号
FROM CJB
WHERE 成绩 >= 80
GROUP BY 学号
HAVING COUNT(*) > 2

【例4.64】 查找通信工程专业平均成绩在85分以上的学生的学号和平均成绩。
SELECT 学号, AVG(成绩) AS '平均成绩'
FROM CJB
WHERE 学号 IN
(
SELECT 学号
FROM XSB
WHERE 专业 = '通信工程'
)
GROUP BY 学号
HAVING AVG(成绩) > =85
执行结果如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
【例4.65】  将通信工程专业的学生按出生时间先后顺序排序。
SELECT *
FROM XSB
WHERE 专业= '通信工程'
ORDER BY 出生时间

【例4.66】 将计算机专业学生的“计算机基础”课程成绩按降序排列。
SELECT 姓名, 课程名, 成绩
FROM XSB, KCB, CJB
WHERE XSB.学号 = CJB.学号
AND CJB.课程号 = KCB.课程号
AND 课程名= '计算机基础'
AND 专业= '计算机'
ORDER BY 成绩 DESC
1
2
3
4
5
6
7
8
【例4.70】  查找学号为081101和学号为081210的两位同学的信息。
SELECT *
FROM XSB
WHERE 学号= '081101'
UNION ALL
SELECT *
FROM XSB
WHERE 学号= '081210'
1
2
3
4
5
6
7
8
9
10
11
【例4.42】  查找PXSCJ数据库每个学生的情况以及选修的课程情况。

USE PXSCJ
GO
SELECT XSB.* , CJB.*
// .字段名,*所有字段
FROM XSB , CJB
WHERE XSB.学号 = CJB.学号
// 表.字段 重复一定有,唯一可以省略

结果表将包含XSB表和CJB表的所有列。

4章

| 专门的关系运算包括:选择/投影和连接

https://zlogs.net/note/learn-database-principle/page/1037.html?h=%E6%8A%95%E5%BD%B1

https://zlogs.net/note/learn-database-principle/page/1041.html?h=%E6%8A%95%E5%BD%B1

| 外连接分类LEFT | RIGHT | FULL

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
【例4.44】  查找选修了206号课程且成绩在80分以上的学生姓名及成绩。

SELECT 姓名, 成绩
FROM XSB , CJB
WHERE XSB.学号 = CJB.学号 AND 课程号 = '206' AND 成绩 >= 80

//先筛选符合条件,再和xsb连接

【例4.45】 查找选修了“计算机基础”课程且成绩在80分以上的学生学号、姓名、课程名及成绩。
SELECT XSB.学号, 姓名, 课程名, 成绩
FROM XSB , KCB , CJB
WHERE XSB.学号 = CJB.学号
AND KCB.课程号 = CJB.课程号
AND 课程名 = '计算机基础'
AND 成绩 >= 80

【例4.46】 查找PXSCJ数据库每个学生的情况以及选修的课程情况。
SELECT *
FROM XSB INNER JOIN CJB
ON XSB.学号 =CJB.学号
执行的结果将包含XSB表和CJB表的所有字段(不去除重复字段——学号)。

内连接是系统默认的,可以省略INNER关键字。使用内连接后仍可使用WHERE子句指定条件。

【例4.47】 用FROM子句的JOIN关键字表达下列查询:查找选修了206号课程且成绩在80分以上的学生姓名及成绩。
SELECT 姓名, 成绩
FROM XSB JOIN CJB
ON XSB.学号 = CJB.学号
WHERE 课程号 = '206' AND 成绩>=80



| 在使用视图时,要注意下列事项:

  • (1)只有在当前数据库中才能创建视图。视图的命名必须遵循标识符命名规则,不能与表同名。
  • (2)不能把规则、默认值或触发器与视图相关联。

https://zlogs.net/note/learn-sql/page/11273.html

l 外连接。指定了OUTER关键字的为外连接,外连接的结果表不但包含满足连接条件的行,还包括相应表中的所有行。外连接包括以下三种。

  • 左外连接(LEFT OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括左表的所有行;
  • 右外连接(RIGHT OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括右表的所有行;
  • 完全外连接(FULL OUTER JOIN):结果表中除了包括满足连接条件的行外,还包括两个表的所有行。
  • 其中的OUTER关键字均可省略。
1
2
3
4
5
6
7
8
9
【例4.50】  查找所有学生情况,以及他们选修的课程号,若学生未选修任何课,也要包括其情况。
SELECT XSB.* , 课程号
FROM XSB LEFT OUTER JOIN CJB
ON XSB.学号 = CJB.学号
本例执行时,若有学生未选任何课程,则结果表中相应行的课程号字段值为NULL
【例4.51】 查找被选修了的课程的选修情况和所有开设的课程名。
SELECT CJB.* , 课程名
FROM CJB RIGHT JOIN KCB
ON CJB.课程号= KCB.课程号

l 使用视图有下列优点:

  • (1)为用户集中数据简化用户的数据查询和处理。有时用户所需要的数据分散在多个表中,定义视图可将它们集中在一起,从而方便用户进行数据查询和处理。
  • (2)屏蔽数据库的复杂性。用户不必了解复杂的数据库中的表结构,并且数据库表的更改也不影响用户对数据库的使用。
  • (3)简化用户权限的管理只需授予用户使用视图的权限,而不必指定用户只能使用表的特定列,也增加了安全性。
  • (4)便于数据共享。各用户不必都定义和存储自己所需的数据,而可共享数据库的数据,这样,同样的数据只需存储一次。
  • (5)可以重新组织数据以便输出到其他应用程序中
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
【例7.16】  在PXSCJ数据库中创建视图stu_view,包含学生学号、专业、课程号、成绩。该视图依赖于表XSB和CJB,是不可更新视图。可以在视图上创建INSTEAD OF触发器,当向视图中插入数据时分别向表XSB和CJB插入数据,从而实现向视图插入数据的功能。
首先创建视图:
CREATE VIEW stu_view
AS
SELECT XSB.学号, 专业, 课程号, 成绩
FROM XSB, CJB
WHERE XSB.学号=CJB.学号
创建INSTEAD OF触发器:
CREATE TRIGGER InsteadTrig
ON stu_view
INSTEAD OF INSERT /*替代视图原有insert操作*/
AS
BEGIN
DECLARE @XH char(6), @XM char(8),
@ZY char(12), @KCH char(3), @CJ int
SET @XM='佚名'
SELECT @XH=学号, @ZY=专业, @KCH=课程号, @CJ=成绩
FROM inserted
INSERT INTO XSB(学号, 姓名, 专业)
VALUES(@XH, @XM, @ZY)
INSERT INTO CJB VALUES(@XH, @KCH, @CJ)
END

l 用来创建视图的SELECT语句,有以下限制:

  • ① 定义视图的用户必须对所参照的表或视图有查询(即可执行SELECT语句)权限;
  • ② 不能使用COMPUTE或COMPUTE BY子句;
  • ③ 不能使用ORDER BY子句;
  • ④ 不能使用INTO子句;
  • ⑤ 不能在临时表或表变量上创建视图。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
【例4.75】  创建CS_KC视图,包括计算机专业各学生的学号、其选修的课程号及成绩。要保证对该视图的修改都符合“专业为计算机”这一条件。
USE PXSCJ
GO
CREATE VIEW CS_KC WITH ENCRYPTION
AS
SELECT XSB.学号, 课程号, 成绩
FROM XSB, CJB
WHERE XSB.学号 =CJB.学号 AND 专业 = '计算机'
WITH CHECK OPTION

【例4.76】 创建计算机专业学生的平均成绩视图CS_KC_AVG,包括学号(在视图中列名为num)和平均成绩(在视图中列名为score_avg)。
CREATE VIEW CS_KC_AVG(num,score_avg)
AS
SELECT 学号, AVG(成绩)
FROM CJB
GROUP BY 学号
在一般情况下,如果视图为下列格式,则称其为分区视图。
CREATE VIEW view_name
AS
SELECT <select_list1>
FROM T1
UNION ALL
SELECT <select_list2>
FROM T2
UNION ALL
...
SELECT <select_listn>
FROM Tn

【例4.77】 使用视图CS_KC查找计算机专业的学生学号和选修的课程号。
SELECT 学号, 课程号
FROM CS_KC
【例4.78】 查找平均成绩在80分以上的学生的学号和平均成绩。
本例首先创建学生平均成绩视图XS_KC_AVG,包括学号(在视图中列名为num)和平均成绩(在视图中列名为score_avg)。
CREATE VIEW XS_KC_AVG ( num,score_avg )
AS
SELECT 学号, AVG(成绩)
FROM CJB
GROUP BY 学号

再对XS_KC_AVG视图进行查询。
SELECT *
FROM XS_KC_AVG
WHERE score_avg >= 80

l 游标分类及SQL Server对游标的使用过程:

  • 前端(客户端)游标和后端(服务器端)游标。“声明游标→打开游标→读取数据→关闭游标→删除游标”。

使用两种方式定义列别名【例4.4】 替换查询结果中的数据例4.5

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
【例4.4】  查询XSB表中计算机系同学的学号、姓名和总学分,结果中各列的标题分别指定为number、name和mark。
USE PXSCJ
GO
SELECT 学号 AS number, 姓名 AS name, 总学分 AS mark
FROM XSB
WHERE 专业= '计算机'

更改查询结果中的列标题也可以使用column_alias=expression的形式。例如,
SELECT number= 学号, name = 姓名, mark = 总学分
FROM XSB
WHERE 专业= '计算机'
该语句的执行结果与上例的结果完全相同。
当自定义的列标题中含有空格时,必须使用引号将标题括起来。例如,
SELECT 'Student number' = 学号,姓名 AS 'Student name', mark = 总学分
FROM XSB
WHERE 专业= '计算机'

【例4.5】 查询XSB表中计算机系各同学的学号、姓名和总学分,对其总学分按以下规则进行替换:若总学分为空值,则替换为“尚未选课”;若总学分小于50,则替换为“不及格”;若总学分在5052之间,则替换为“合格”;若总学分大于52,则替换为“优秀”。列标题更改为“等级”。
USE PXSCJ
GO
SELECT 学号, 姓名, 等级=
CASE
WHEN 总学分 IS NULL THEN '尚未选课'
WHEN 总学分 < 50 THEN '不及格'
WHEN 总学分 >=50 and 总学分<=52 THEN '合格'
ELSE '优秀'
END
FROM XSB
WHERE 专业= '计算机'
GO

常用聚合函数的使用4.9-4.15

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
SUM /AVG ( [ ALL | DISTINCT ] expression )
​```sql
其中,expression是常量、列、函数或表达式,其数据类型只能是intsmallint、tinyint、bigintdecimalnumericfloatreal、money和smallmoney。ALL表示对所有值进行运算,DISTINCT表示去除重复值,默认为ALL。SUM / AVG忽略NULL值。
​```sql
【例4.9】 求选修101课程的学生的平均成绩。
SELECT AVG(成绩) AS '课程101平均成绩'
FROM CJB
WHERE 课程号 = '101'

使用聚合函数作为SELECT的选择列时,若不为其指定列标题,则系统将对该列输出标题“无列名”。
【例4.10】 求学号为081101的同学所学课程的总成绩。
SELECT SUM(成绩) AS '课程总成绩'
FROM CJB
WHERE 学号 = '081101';
结果为234

【例4.11】 求选修101课程的学生的最高分和最低分。
SELECT MAX(成绩) AS '课程101的最高分' , MIN(成绩) AS '课程101的最低分'
FROM CJB
WHERE 课程号 = '101'
执行结果如下:
|课程101的最高分 |课程101的最低分 |
|--- |--- |
| 95 | 62 |

【例4.12】 求学生的总数。
SELECT COUNT(*) AS '学生总数'
FROM XSB
学生总数为22,使用COUNT(*)时将返回检索行的总数目,不论其是否包含 NULL值。
【例4.13】 统计备注不为空的学生数。
SELECT COUNT(备注) AS '备注不为空的学生数'
FROM XSB;

【例4.14】 统计总学分在50分以上的人数。
SELECT COUNT(总学分) AS '总学分在50分以上的人数'
FROM XSB
WHERE 总学分>50;
执行结果为2
【例4.15】 求选修了课程的学生总数。
SELECT COUNT(DISTINCT 学号)
FROM CJB
COUNT_BIG函数的格式、功能与COUNT函数都相同,区别仅在于COUNT_BIG返回bigint类型值。

分类汇总的使用

https://zlogs.net/note/learn-sql/page/11272.html?h=%E5%88%86%E7%B1%BB%E6%B1%87%E6%80%BB

1
2
3
4
5
6
7
8
ORDER BY子句可以与COMPUTE BY子句一起使用,在对结果排序的同时还产生附加的汇总行。COMPUTE子句用于分类汇总,将产生额外的汇总行。格式为
[ COMPUTE { 聚合函数名(expression)} [ ,…n ] [ BY expression [ ,…n ] ] ]
【例4.67】 查找通信工程专业学生的学号、姓名、出生时间,并产生一个学生总人数行。
SELECT 学号, 姓名, 出生时间
FROM XSB
WHERE 专业= '通信工程'
COMPUTE COUNT(学号)
执行结果如下:

5章

l 创建用户自定义数据类型时首先应考虑如下三个属性:

l 常规标识符:

  • 以ASCII字母、Unicode字母、下划线(_)、@或#开头,
  • 后续可跟一个或若干个ASCII字符、Unicode字符、下划线(_)、美元符号($)、@或#,
  • 但不能全为下划线(_)、@或#。
  • 标识符允许的最大长度为128个字符。

l 局部变量的赋值。

  • 当声明局部变量后,可用SET或SELECT语句为其赋值。
  • 一个SELECT语句可以初始化多个局部变量。

l RAND ([ seed ] ) 返回0~1之间的一个随机值。

  • 参数seed是指定种子值的整型表达式,返回值类型为float。

  • 如果未指定seed,则随机分配种子值。

  • 对于指定的种子值,返回的结果始终相同。

  • 【例5.24】  以下程序通过RAND函数返回随机值。
    DECLARE @count int
    SET @count = 5
    SELECT  RAND(@count)
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95

    +

    + <https://zlogs.net/note/learn-sql/page/11281.html?h=RAND>

    l 根据用户定义函数返回值的类型,可将用户定义函数分为如下两个类别。

    + (1)标量函数
    + (2)表值函数

    l 什么是SQL语言,微软SQL-Serve和甲骨文公司Oracle使用的SQL语言各是什么?

    > SQL语言的全名是结构化查询语言(Structured Query Language),是用于数据库中的标准数据查询语言,IBM公司最早使用该语言在其开发的数据库系统中。1986年10月,美国ANSI对 SQL进行规范后,以此作为关系数据库管理系统的标准语言。

    > 微软公司的MS SQL-Server支持的是T-SQL,而甲骨文公司的Oracle 数据库所使用的SQL语言则是PL-SQL。

    【例5.20】 将学号为081101的学生的总学分使用循环修改到60,每次只加2,并判断循环了多少次。



    # **6章**

    l 计算列为**text、ntext或image**列时也**不能在该列上创建索引**。

    l 规则是一组使用T-SQL语句组成的条件语句,规则提供了另外一种在数据库中实现域完整性与用户定义完整性的方法。规则对象的使用方法与默认值对象的使用步骤类似。

    + ① 定义规则对象;

    + ② 将规则对象绑定到列或用户自定义类型。

    + <https://zlogs.net/note/learn-sql/page/11339.html?h=%E5%AE%9A%E4%B9%89%E8%A7%84%E5%88%99%E5%AF%B9%E8%B1%A1>

    + ```sql

    规则是一组使用T-SQL语句组成的条件语句,规则提供了另外一种在数据库中实现域完整性与用户定义完整性的方法。规则对象的使用方法与默认值对象的使用步骤类似。
    ① 定义规则对象;
    ② 将规则对象绑定到列或用户自定义类型。
    在SQL Server 2008中,规则对象的定义可以利用CREATE RULE语句来实现。
    (1)规则对象的定义。
    语法格式:
    CREATE RULE [ schema_name. ] rule_name
    AS condition_expression
    [ ; ]

    (2)将规则对象绑定到用户定义数据类型或列。
    将规则对象绑定到列或用户定义数据类型中可以使用系统存储过程sp_bindrule。
    语法格式:
    sp_bindrule [ @rulename = ] 'rule' ,
    [ @objname = ] 'object_name'
    [ , [ @futureonly = ] 'futureonly_flag' ]
    (3)应用举例。
    【例6.18】 如下程序创建一个规则,并绑定到表KCB的课程号列,用于限制课程号的输入范围。
    USE PXSCJ
    GO
    CREATE RULE kc_rule
    AS @range like '[1-5][0-9][0-9]'
    GO
    EXEC sp_bindrule 'kc_rule', 'KCB.课程号' /*执行存储过程使用EXEC命令*/
    GO
    程序如果正确执行将提示:“已将规则绑定到表的列”。


    【例6.19】 创建一个规则,用以限制输入到该规则所绑定的列中的值只能是该规则中列出的值。
    CREATE RULE list_rule
    AS @list IN ('C语言', '离散数学', '微机原理')
    GO
    EXEC sp_bindrule 'list_rule', 'KCB.课程名'
    GO

    【例6.20】 如下程序定义一个用户数据类型course_num,然后将前面定义的规则“kc_rule”绑定到用户数据类型course_num上,最后创建表KCB1,其课程号的数据类型为course_num。
    CREATE TYPE course_num
    FROM char(3) NOT NULL /*创建用户定义数据类型*/
    EXEC sp_bindrule 'kc_rule', 'course_num' /*将规则对象绑定到用户定义数据类型*/
    GO
    CREATE TABLE KCB1
    (
    课程号 course_num, /*将学号定义为course_num类型*/
    课程名 char(16) NOT NULL,
    开课学期 tinyint ,
    学时 tinyint,
    学分 tinyint
    )
    GO

    (4)规则对象的删除。在删除规则对象前,首先应使用系统存储过程sp_unbindrule解除被绑定对象与规则对象之间的绑定关系,使用格式如下:
    sp_unbindrule [@objname =] 'object_name'
    [, [@futureonly =] 'futureonly_flag']
    在解除列或自定义类型与规则对象之间的绑定关系后,就可以删除规则对象了。
    语法格式:
    DROP RULE { [ schema_name . ] rule_name } [ ,...n ] [ ; ]
    【例6.21】 解除规则kc_rule与列或用户定义类型的绑定关系,并删除规则对象kc_rule。
    EXEC sp_unbindrule 'KCB.课程号'
    EXEC sp_unbindrule 'course_num'
    GO
    DROP RULE kc_rule

| 在删除规则对象前,首先应使用系统存储过程sp_unbindrule解除被绑定对象与规则对象之间的绑定关系

l 建立索引主要有以下作用:

  • 快速存取数据;
  • 保证数据记录的唯一性;
  • 实现表与表之间的参照完整性;
  • 在使用ORDER BY、GROUP BY子句进行数据检索时,利用索引可以减少排序和分组的时间。

l 索引的分类及含义:

  • 聚集索引和非聚集索引
    • 聚集索引将数据行的键值在表内排序并存储对应的数据记录,使得数据表物理顺序与索引顺序一致

    • 非聚集索引完全独立于数据行的结构。

    • 只有在表上创建聚集索引时,表内的行才按特定顺序存储,这些行按聚集索引键顺序存储。如果一个表只有非聚集索引,则它的数据行将按无序的堆集方式存储。

    • 利用“T-SQL命令”创建及删除PRIMARY KEY约束或UNIQUE约束
      利用T-SQL命令可以使用两种方式定义约束:作为列的约束或作为表的约束。可以在创建表或修改表时定义。
      (1)在创建表的同时创建PRIMARY KEY约束或UNIQUE约束。
      语法格式:
      CREATE TABLE table_name 
          ( { <列定义> <column_constraint>}[,…n]
            [ <table_constraint> ] [ ,...n ] ) 
      
      其中,<column_constraint>为列的约束,<table_constraint>为表的约束。
      <column_constraint> ::=                                 /*定义列的约束*/
      [ CONSTRAINT constraint_name ]
      { { PRIMARY KEY | UNIQUE }                             /*定义主键与UNIQUE键*/
          [ CLUSTERED | NONCLUSTERED ]                     /*定义约束的索引类型*/
          [WITH ( < index_option > [ , ...n ] ) ]
          [ ON { partition_scheme_name ( partition_column_name ) | filegroup | "default" } ]
       | [ FOREIGN KEY ] <reference_definition>            /*定义外键*/
       | CHECK [ NOT FOR REPLICATION ] ( logical_expression )     /*定义CHECK约束*/
      }
       < table_constraint > ::=                                    /*定义表的约束*/
      [ CONSTRAINT constraint_name ] /*指定名称方便删除*/
      { 
        { PRIMARY KEY | UNIQUE } 
          [ CLUSTERED | NONCLUSTERED ]
              (column [ ASC | DESC ] [ ,...n ] )                     /*定义表的约束时需要指定列*/
          [WITH ( <index_option> [ , ...n ] ) ]
          [ ON { partition_scheme_name (partition_column_name) | filegroup | "default" } ] 
        | FOREIGN KEY ( column [ ,...n ] ) <reference_definition>
        | CHECK [ NOT FOR REPLICATION ] ( logical_expression ) 
      } 
      
      【例6.9】  创建XSB1表(假设XSB1表未创建),并对“学号”字段创建PRIMARY KEY约束,对“姓名”字段定义UNIQUE约束。
      USE PXSCJ
      GO
      CREATE TABLE XSB1
      (
          学号     char(6)     NOT NULL    CONSTRAINT  XH_PK  PRIMARY KEY,
          姓名    char(8)     NOT NULL    CONSTRAINT XM_UK  UNIQUE,
          性别     bit         NOT NULL    DEFAULT 1,
          出生时间     date         NOT NULL,
          专业     char(12)     NULL,
          总学分     int         NULL,
          备注     varchar(500) NULL
      ) 
      
      【例6.10】  创建一个course_name表来记录每门课程的学生学号、姓名、课程号、学分和毕业日期。其中,学号、课程号和毕业日期构成复合主键,学分为唯一键。
      CREATE TABLE course_name
      (
          学号      varchar(6)  NOT NULL,
          姓名      varchar(8)  NOT NULL,
          毕业日期date          NOT NULL,
          课程号    varchar(3) ,
          学分        tinyint,
          PRIMARY  KEY (学号, 课程号, 毕业日期),
          CONSTRAINT XF_UK  UNIQUE (学分)
      )
      
      (2)通过修改表创建PRIMARY KEY约束或UNIQUE约束。
      使用ALTER TABLE语句中的ADD子句可以为表中已存在的列或新列定义约束,语法格式参见第3章中ALTER TABLE语句的ADD子句。
      【例6.11】  修改例6.14中的XSB1表,向其中添加一个“身份证号码”字段,对该字段定义UNIQUE约束。对“出生时间”字段定义UNIQUE约束。
      ALTER TABLE  XSB1    
          ADD    身份证号码 char(20) 
              CONSTRAINT SF_UK   UNIQUE NONCLUSTERED (身份证号码)
      GO
      ALTER TABLE  XSB1    
          ADD    CONSTRAINT CJSJ_UK  UNIQUE NONCLUSTERED (出生时间)
      
      (3)删除PRIMARY KEY约束或UNIQUE约束。
      删除PRIMARY KEY约束或UNIQUE约束需要使用ALTER TABLE的DROP子句。
      语法格式:
      ALTER TABLE table_name 
          DROP CONSTRAINT constraint_name [ ,...n ] 
      【例6.12】  删除例6.14中创建的PRIMARY KEY约束和UNIQUE约束。
      ALTER TABLE  XSB1 
          DROP    CONSTRAINT XH_PK, XM_UK
      GO
      
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
      33
      34
      35
      36
      37
      38
      39
      40
      41
      42
      43
      44
      45
      46
      47
      48
      49
      50
      51
      52
      53
      54
      55
      56
      57
      58
      59
      60
      61
      62
      63
      64
      65
      66
      67
      68
      69
      70
      71
      72
      73
      74
      75
      76
      77
      78

      +

      l 数据完整性的分类

      + 数据完整性是指数据库中的数据在逻辑上的一致性和准确性。数据完整性一般包括三种。
      + 1.实体完整性--主键约束
      + 2.域完整性--check 列完整性
      + 3.参照完整性--外键 引用完整性
      + <https://zlogs.net/note/learn-sql/page/11339.html>

      l 如果定义了两个表之间的参照完整性,则要求:

      + (1)从表不能引用不存在的键值。

      + > 例如,CJB表中行记录出现的学号必须是XSB表中已存在的学号。

      + (2)如果主表中的键值更改了,那么在整个数据库中,对从表中该键值的所有引用要进行一致的更改。

      + > 例如,如果对XSB表中的某一学号修改,则CJB表中所有对应学号也要进行相应的修改。

      + (3)如果主表中没有关联的记录,则不能将记录添加到从表。

      + (4)如果要删除主表中的某一记录,则应先删除从表中与该记录匹配的相关记录。

      l PRIMARY KEY约束与UNIQUE约束的主要区别如下:

      (1)一个数据表只能创建一个PRIMARY KEY约束,但一个表中可根据需要对表中不同的列创建若干个UNIQUE约束。

      (2)PRIMARY KEY字段的值不允许为NULL,而UNIQUE字段的值可取NULL。

      (3)一般在创建PRIMARY KEY约束时,系统会自动产生索引,索引的默认类型为簇索引。在创建UNIQUE约束时,系统会自动产生一个UNIQUE索引,索引的默认类型为非簇索引。

      创建表的同时添加外键约束,例6.22-6.23

      ```sql
      利用“T-SQL命令”定义表间的参照关系
      前面已介绍了创建主键(PRIMARY KEY约束)及唯一键(UNIQUE约束)的方法,在此将介绍通过T-SQL命令创建外键的方法。
      (1)创建表的同时定义外键约束。
      语法格式在6.3.2小节中已经列出,这里只列出定义外键部分的语法。
      CREATE TABLE table_name /*指定表名*/
      (<column_definition>
      [ CONSTRAINT constraint_name ]
      [ FOREIGN KEY ][ ( column [ ,...n ] )] <reference_definition>
      )
      其中,
      <reference_definition>::=
      REFERENCES referenced_table_name [ ( ref_column [ ,...n ] ) ]
      [ ON DELETE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
      [ ON UPDATE { NO ACTION | CASCADE | SET NULL | SET DEFAULT } ]
      /*忽略, 级联跟着变, */
      [ NOT FOR REPLICATION ]

      【例6.22】 创建stu表,要求stu表中所有的学生学号都必须出现在XSB表中,假设已经使用“学号”列作为主键创建了XSB表。
      USE PXSCJ
      GO
      CREATE TABLE stu
      (
      学号 char(6) NOT NULL FOREIGN KEY (学号) REFERENCES XSB (学号),
      姓名 char(8) NOT NULL,
      出生时间 datetime NULL
      )

      【例6.23】 创建point表,要求表中所有的学号、课程号组合都必须出现在CJB表中。
      CREATE TABLE point
      (
      学号 char(6) NOT NULL,
      课程号 char(3) NOT NULL,
      成绩 int NULL,
      CONSTRAINT FK_point FOREIGN KEY (学号,课程号) REFERENCES CJB (学号,课程号)
      ON DELETE NO ACTION
      )
      (2)通过修改表定义外键约束。
      【例6.24】 假设KCB表为主表,KCB的“课程号”字段已定义为主键。CJB表为从表,如下示例用于将CJB表的“课程号”字段定义为外键。
      ALTER TABLE CJB
      ADD CONSTRAINT kc_foreign
      FOREIGN KEY (课程号)
      REFERENCES KCB(课程号 )

7章

l 通过EXECUTE或EXEC命令可以执行一个已定义的存储过程

l 触发器分为两大类:DML触发器和DDL触发器。

l 在执行UPDATE触发器时,将触发器表的原记录保存到deleted临时表中,将修改后的记录保存到inserted临时表中。

l INSTEAD OF触发器触发时只执行触发器内部的SQL语句,而不执行激活该触发器的SQL语句。一个表或视图中只能有一个INSTEAD OF触发器。

l 使用存储过程的优点如下:

  • (1)存储过程在服务器端运行,执行速度快。
  • (2)存储过程执行一次后,就驻留在高速缓冲存储器,在以后的操作中,只需从高速缓冲存储器中调用已编译好的二进制代码执行,提高了系统性能。
  • (3)使用存储过程可以完成所有数据库操作,并可通过编程方式控制对数据库信息访问的权限,确保数据库的安全。
  • (4)自动完成需要预先执行的任务。

l 存储过程的类型:

  • 系统存储过程、扩展存储过程、用户存储过程

例7.4存储过程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
4)使用带有通配符参数的存储过程。
【例7.4】 从三个表的连接中返回指定学生的学号、姓名、所选课程名称及该课程的成绩。该存储过程在参数中使用了模式匹配,如果没有提供参数,则使用预设的默认值。
CREATE PROCEDURE st_info @name varchar(30) = '李%' /*默认值是李%*/
AS
SELECT a.学号,a.姓名,c.课程名,b.成绩
FROM XSB a INNER JOIN CJB b
ON a.学号 =b.学号 INNER JOIN KCB c
ON c.课程号= b.课程号
WHERE 姓名 LIKE @name
GO
执行存储过程:
EXECUTE st_info /*参数使用默认值*/
或者
EXECUTE st_info '王%' /*传递给@name 的实参为'王%'*/

例7.12-7.15触发器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
4)创建UPDATE触发器。UPDATE触发器在对触发器表执行UPDATE语句后触发。在执行UPDATE触发器时,将触发器表的原记录保存到deleted临时表中,将修改后的记录保存到inserted临时表中。
【例7.12】 创建触发器,当修改XSB表中的学号时,同时也要将CJB表中的学号修改成相应的学号(假设XSB表和CJB表之间没有定义外键约束)。
CREATE TRIGGER xsb_update
ON XSB AFTER UPDATE
AS
BEGIN
DECLARE @old_num char(6), @new_num char(6)
SELECT @old_num=学号 FROM deleted /*更新的本质,删除以前的,出入新的*/
SELECT @new_num=学号 FROM inserted
UPDATE CJB SET 学号=@new_num WHERE 学号=@old_num
END
接着修改XSB表中的一行数据,并查看触发器执行结果:
UPDATE XSB SET 学号='081120' WHERE 学号='081101'
GO
SELECT * FROM CJB WHERE 学号='081120'
执行结果如下:

5)创建DELETE触发器。
【例7.13】 在删除XSB表中的一条学生记录时将CJB表中该学生的相应记录也删除。
CREATE TRIGGER xsb_delete
ON XSB AFTER DELETE
AS
BEGIN
DELETE FROM CJB
WHERE 学号 IN(SELECT 学号 FROM deleted)
END


【例7.14】 在KCB表中创建UPDATEDELETE触发器,当修改或删除KCB表中的“课程号”字段时,同时修改或删除CJB表中的该课程号。
CREATE TRIGGER kcb_trig
ON KCB AFTER UPDATE, DELETE
AS
BEGIN
IF (UPDATE(课程号))
UPDATE CJB SET 课程号=(SELECT 课程号 FROM inserted)
WHERE 课程号=(SELECT 课程号 FROM deleted)
ELSE
DELETE FROM CJB
WHERE 课程号 IN(SELECT 课程号 FROM deleted)
END



6)创建INSTEAD OF触发器。AFTER触发器是在触发语句执行后触发的,与AFTER触发器不同的是,INSTEAD OF触发器触发时只执行触发器内部的SQL语句,而不执行激活该触发器的SQL语句。一个表或视图中只能有一个INSTEAD OF触发器。
【例7.15】 创建表table2,值包含一列a,在表中创建INSTEAD OF INSERT触发器,当向表中插入记录时显示相应消息。
USE PXSCJ
GO
CREATE TABLE table2(a int)
GO
CREATE TRIGGER table2_insert
ON table2 INSTEAD OF INSERT
AS
PRINT 'INSTEAD OF TRIGGER IS WORKING'
向表中插入一行数据:
INSERT INTO table2 VALUES(10)

8章

l 数据库需备份的内容可分为数据文件(又分为主要数据文件和次要数据文件)、日志文件两部分。

l 在SQL Server 2008中,允许使用两种类型的备份介质。(1)硬盘、磁带

l 当系统发现出现了以下情况时,恢复操作将不进行:

  • (1)指定要恢复的数据库已存在,但在备份文件中记录的数据库与其不同;
  • (2)服务器上数据库文件集与备份中的数据库文件集不一致;
  • (3)未提供恢复数据库所需的所有文件或文件组。

l 创建命名备份设备时,要注意以下几点:

  • ① SQL Server 2008将在系统数据库master的系统表sysdevice中创建该命名备份设备的物理名和逻辑名。
  • ② 必须指定该命名备份设备的物理名和逻辑名,当在网络磁盘上创建命名备份设备时要说明网络磁盘文件路径名。

l 在复制数据库文件时,一定要先通过SQL Server配置管理器停止SQL Server服务,然后才能复制数据文件,否则无法复制。

l 具有下列角色的成员可以做备份操作:

  • (1)固定的服务器角色sysadmin(系统管理员)。
  • (2)固定的数据库角色db_owner(数据库所有者)。
  • (3)固定的数据库角色db_backupoperator(允许进行数据库备份的用户)。

|SQL Server 2008中有4种备份方法:

  • (1)完全数据库备份
  • (2)数据库和事务日志备份
  • (3)差异备份
  • (4)数据库文件或文件组备份

l 数据库文件或文件组备份时,要注意以下几点:

  • (1)必须指定文件或文件组的逻辑名;
  • (2)必须执行事务日志备份,以确保恢复后的文件与数据库其他部分的一致性;
  • (3)应轮流备份数据库中的文件或文件组,以使数据库中的所有文件或文件组都定期得到备份;