文章目录
- 一. 多表查询
- 1. 等值连接
- 2. 自然连接
- 3. 自身连接
- 4. 复合条件连接
- 5. 内连接
- 二. 联合查询
- 1. UNION 运算符
- 2. INTERSECT 运算符
- 3. EXCEPT 运算符
- 三. 子查询
- 1. 一般子查询
- 2. 带有 IN 或 NOT IN 的子查询
- 3. 带有比较运算符的子查询
- 4. 带有 EXISTS 运算符的子查询
- 5. 在查询的基础上创建新表
- 四. 索引
- 1. 创建索引
- 2. 禁用索引
- 3. 其他操作
- 五. 视图
- 1. 单表视图
- 2. 多表视图
- 3. 基于视图的视图
- 4. 基于视图的操作
- 5. 修改视图
- 6. 删除视图
- 六. 存储过程应用
- 1. 创建并执行存储过程
- 2. 带参数的存储过程
- 3. 创建并执行带有通配符参数的存储过程
- 4. 创建并执行带有输出参数的存储过程
- 5. 存储过程的重编译处理
- 6. 查看存储过程
- 7. 修改存储过程
- 8. 删除存储过程
一. 多表查询
1. 等值连接
采用 等值连接 的方法,查询教学计划及开设课程的详细情况。教学计划( 课程号,专业代码,课程类型,开课学期,学时 ),课程( 课程号,课程名,课程性质,学分 )
代码如下:
SELECT 教学计划.*, 课程.*
FROM 教学计划,课程
WHERE 教学计划.课程号 = 课程.课程号
2. 自然连接
采用自然连接的方法,查询教学计划及开设课程的详细情况。
代码如下:
SELECT 教学计划.课程号, 专业代码, 课程类型, 开课学期, 学时, 课程名, 课程性质, 学分
FROM 教学计划,课程
WHERE 教学计划.课程号 = 课程.课程号
3. 自身连接
采用自身连接的方法,查找 不同课程成绩相同 的学生的学号、课程号和成绩。选课( 学号,课程号,成绩,补考成绩,学分 )
分析: 若要在一个表中查找具有相同字段值的行,则可以使用自身连接。使用自身连接时需为表指定两个别名,且对所有列的引用均要用别名限定。
代码如下:
SELECT 表1.学号, 表1.课程号, 表1.成绩
FROM 表1, 表2
WHERE 表1.成绩 = 表2.成绩 AND 表1.学号 = 表2.学号 AND 表1.课程号 <> 表2.课程号
4. 复合条件连接
采用复合条件连接方法,查找选修了 “ 电子商务 ” 课程且成绩在 60 分及以上的学生学号、姓名、课程名及成绩。课程( 课程号,课程名,课程性质,学分 ),选课( 学号,课程号,成绩,补考成绩,学分 )。
分析:本例中涉及到数据库中的学生基本信息表、选课表、课程表等3个表。要建立多个连接条件,在多表操作中,复合条件连接( 多个连接条件 )的使用最为广泛。
代码如下:
SELECT 学生基本信息.学号, 姓名, 课程.课程名, 选课.成绩
FROM 学生基本信息, 课程, 选课
WHERE 学生基本信息.学号 = 选课.学号
AND 课程.课程号 = 选课.课程号
AND 课程.课程名 = '电子商务'
AND 选课.成绩 >= 60
在使用 WHERE 子句中的条件表达式时,一般先写自然连接的条件表达式,然后通过逻辑运算符再写出其他的附加限定条件。
5. 内连接
查找数据库中每个学生的基本信息及所在班级情况。班级 ( 班号,班级名称,学生数,专业代码,系部代码,班主任,班长,教室 )
代码如下:
SELECT *
FROM 学生基本信息
INNER JOIN 班级 ON 学生基本信息.班号 = 班级.班号
- 内连接是系统默认的,可以省略 INNER 关键字,使用内连接后,仍可以使用 WHERE 子句指定条件。
二. 联合查询
联合查询也称集合查询。是一种将两个或更多查询的结果,通过 并、交、差 等集合运算合并为单个结果集的一种查询方法。在 SQL Server 2008 中,用于联合查询的运算符有 UNION(求并)、INTERSECT(求交)和 EXCEPT(求差)。
1. UNION 运算符
UNION 运算符是求并操作,能够将两个或更多查询结果顺序连接,合并为单个结果集,该结果集包含联合查询中的所有查询的全部行。
语法格式:
SELECT 语句1
{ UNION <SELECT语句2> } […n]
语法说明如下:
参加 UNION 操作的所有查询中的列数和列的顺序必须相同,对应的数据类型也必须相同。
系统将自动去掉并集的重复记录。
最后结果集的字段名来自第一个 SELECT 语句。利用 UNION 查询 “ 学生基本信息 ” 表中班号为 "520402 " 和 " 620203 " 的学生学号、姓名和班号。
代码如下:
SELECT 学号, 姓名, 班号
FROM 学生基本信息
WHERE 班号 = '520402'
UNION
SELECT 学号, 姓名, 班号
FROM 学生基本信息
WHERE 班号 = '620203'
2. INTERSECT 运算符
INTERSECT 运算符是求交操作,能够将两个或更多查询结果的交集作为联合查询的结果集,该结果集包含两个或更多查询均返回的所有非重复值。
语法格式:
SELECT 语句1 { INTERSECT <SELECT语句2> } […n]
其语法说明与 UNION 运算相同。利用 INTERSECT 查询 “ 选课 ” 表中成绩大于等于 70 与选修了 “ 0310 ” 课程的学生学号、课程号及成绩交集数据。
代码如下:
SELECT 学号, 课程号, 成绩
FROM 选课
WHERE 成绩 >= 70
INTERSECT
SELECT 学号, 课程号, 成绩
FROM 选课
WHERE 课程号 = '0310'
3. EXCEPT 运算符
EXCEPT 运算符是求差操作,从左查询中返回右查询没有找到的所有非重复值,作为联合查询的结果集,该结果集包含两个或更多查询均返回的所有非重复值。
语法格式:
SELECT 语句1
{EXCEPT <SELECT语句2> } [,…n]
其语法说明与 UNION 运算相同。利用 EXCEPT 查询 “ 选课 ” 表中成绩大于 70 与选修了 " 0310 " 课程的学生学号、课程号及成绩差集数据。
代码如下:
SELECT 学号, 课程号, 成绩
FROM 选课
WHERE 成绩 >= 70
EXCEPT
SELECT 学号, 课程号, 成绩
FROM 选课
WHERE 课程号 = '0310'
GO
三. 子查询
子查询是一个 SELECT 查询,它返回单个值且嵌套在 SELECT、INSERT、UPDATE、DELETE 语句或其他子查询中。
任何允许使用表达式的地方都可以使用子查询。子查询也称为内部查询或内部选择,而包含子查询的语句也称为外部查询或外部选择。
子查询能够将比较复杂的查询分解为几个简单的查询,而且子查询可以嵌套,嵌套查询的执行过程是:首先执行内部查询,查询出的数据并不被显示,而是传递给外层语句,并作为外层语句的查询条件来使用。
1. 一般子查询
使用 子查询 查询学生 “ 王一枚 ” 所在的班级名称。
代码如下:
SELECT 班级名称
FROM 班级
WHERE 班号 =
(SELECT 班号
FROM 学生基本信息
WHERE 姓名 = '王一枚')
2. 带有 IN 或 NOT IN 的子查询
在嵌套查询中,子查询的结果通常是一个集合。运算符 IN 或 NOT IN 是嵌套查询中使用最频繁的运算符,用于进行一个给定值是否在子查询结果集中的判断。其语法格式为:
表达式 [NOT] IN(子查询)
说明 : 当表达式与子查询的结果表中的某个值相等时,IN 谓词返回 TRUE,否则返回 FALSE,若使用了 NOT,则返回的值刚好相反。在 “ 学生基本信息 ” 表、“ 选课 ” 表与 “ 课程 ” 表中查询选修了 “ 西方经济学 ” 课程的学生情况。
代码如下:
SELECT *
FROM 学生基本信息
WHERE 学号 IN
(SELECT 学号
FROM 选课
WHERE 课程号 = (
SELECT 课程号
FROM 课程
WHERE 课程名 = '西方经济学'))
3. 带有比较运算符的子查询
带有 IN 运算符的子查询返回的结果是集合,而带有比较运算符( =、<>、>、>=、<、<= ) 的子查询可以返回单值结果,可以看作是 N 子查询的扩展。其语法格式为:
表达式 { < | <= | = | > | >= | != | !< | !> } { ALL | ANY } (子查询)
其中,ALL 和 ANY 说明对比较运算符的限制。
ALL指定表达式要与子查询的结果集中的每个值都进行比较,当表达式与每个值都满足比较的关系时,才回返 TRUE,否则返回 FALSE。ANY 表示表达式只要与子查询结果集中的某个值满足比较的关系时,就返回 TRUE,否则返回 FALSE。在 “ 教师 ” 表与 “ 系部 ” 表中查询其他系中比 “ 航海系 ” 任一教师年龄小的教师基本信息。
代码如下:
SELECT * FROM 教师
WHERE 出生日期 > ANY(SELECT 出生日期
FROM 教师
WHERE 系部代码 = (SELECT 系部代码
FROM 系部
WHERE 系部名称 = '航海系'))
AND
系部代码 <> (SELECT 系部代码
FROM 系部
WHERE 系部名称 = '航海'
ORDER BY 出生日期 ASC
在 “ 教师 ” 表中查询与 “ 赵安 ” 同在一个系的教师基本信息。
代码如下:
SELECT * FROM 教师
WHERE 系部代码 =
(SELECT 系部代码
FROM 教师
WHERE 姓名 = '赵安')
4. 带有 EXISTS 运算符的子查询
使用 EXISTS 运算符后,子查询不返回任何数据,主要用于测试子查询的结果是否为空表。若子查询的结果集不为空,则 EXISTS 返回 TRUE,否则返回 FALSE。EXISTS 还可与 NOT 结合使用,即 NOT EXISTS,其返回值与 EXISTS 则刚好相反,其语法格式为:
[NOT] EXISTS (子查询)用 EXISTS 运算符查询在 “ 教师 ” 表中与 “ 赵安 ” 同在一个系的教师基本信息。
代码如下:
SELECT *
FROM 教师
AS
T1 WHERE EXISTS
(SELECT* FROM 教师
AS T2
WHERE T2.系部代码 = T1.系部代码 AND T2.姓名 = '赵安')
从 STUMS 数据库中,查询没有选修过任何课程的学生的学号和姓名。
代码如下:
SELECT 学号, 姓名
FROM 学生基本信息
WHERE NOT EXISTS (SELECT *
FROM 选课
WHERE 学号 = 学生基本信息.学号)
GO
5. 在查询的基础上创建新表
使用 SELECT 的 INTO 子句可以创建新表来保存查询结果。新表可以是一个永久表或一个临时表。
在 “ 学生基本信息 ” 表与 “ 班级 ” 表中查询学生姓名和班级名,将结果行插入到新表 “ 学生_班级 ” 中。
代码如下:
SELECT 姓名, 班级名称
INTO 学生_班级
FROM 学生基本信息,班级
WHERE 学生基本信息.班号 = 班级.班号
创建一个空的 “ 教师 ” 表的副本
代码如下:
SELECT *
INTO 教师副本
FROM 教师
WHERE 1>3
注:此例中只需创建一个空表,而不需要原表任何记录,可以采用在 WHERE 子句的条件设为“假”的方法。
四. 索引
1. 创建索引
- 在 STUMS 数据库的班级表上按班号创建一个名为 bj_bh_index 唯一聚集索引。
USE STUMS
GO
CREATE UNIQUE CLUSTERED INDEX bj_bh_index ON 班级(班号)
GO
- 在 STUMS 数据库的班级表上按班级名称创建一个名为 bj_bjmc_index 的唯一非聚集索引。
USE STUMS
GO
CREATE UNIQUE NONCLUSTERED INDEX bj_bjmc_index ON 班级(班级名称)
GO
在 STUMS 数据库的 “ 学生基本信息 ” 表上按学号建立聚集索引 xs_xh_index。
若本例曾用 SSMS 创建过,若再用命令创建,将会导致索引创建失败。为避免在同一表中,重复创建聚集索引或同名创建索引,可使用短语 WITH DROP_EXISTING 删除己存在的索引。
代码如下:
USE STUMS
GO
CREATE CLUSTERED INDEX xs_xh_index ON 学生基本信息(学号)
WITH DROP_EXISTING
GO
在 STUMS 数据库的班级表中,按 bj_bjmc_index 索引指定的顺序,查询班级信息。
USE STUMS
GO
SELECT *
FROM 班级
WITH (INDEX(bj_bjmc_index))
GO
在 STUMS 数据库的选课表上按 学号 + 课程号 建立唯一非聚集索引 xk_xhkch,其填充因子为 60。
USE STUMS
GO
CREATE UNIQUE NONCLUSTERED INDEX xk_xhkch ON 选课(学号,课程号)
WITH FILLFACTOR = 60
GO
2. 禁用索引
禁用 “ 学生基本信息 ” 表的非聚集索引 xs_xm_index。
代码如下:
USE STUMS
GO
ALTER INDEX xs_xm_index ON 学生基本信息 DISABLE
GO
当使用 xs_xm _index 索引查询学生基本信息数据时,系统会提示此索引已被禁用。
3. 其他操作
重新组织 “ 学生基本信息 ” 表上的聚集索引 xs_xh_index 。
代码如下:
USE STUMS
ALTER INDEX xs_xh_index ON 学生基本信息 REORGANIZE
重新命名索引 xk_xhkch 为 xk_xhkch_index。
EXEC sp_rename '学生基本信息. xk_xhkch','xk_xhkch_index'
使用填充因子值 70,重建班级表上所有索引。
USE STUMS
GO
ALTER INDEX ALL ON 班级
REBUILD
WITH (FILLFACTOR = 70)
GO
查看班级表上的索引信息。
EXEC sp_helpindex '班级'
EXEC sp_help '班级'
删除班级表上的所有索引。
DROP INDEX 班级
使用DROP INDEX语句删除学生基本信息表上的 xs_new_index 索引和表上的 js_bhkchbh_index 索引。
代码如下:
DROP INDEX 学生基本信息.xs_new_index,教师任课.js_bhkchbh_index
说明:
删除表或视图时,自动删除在表或视图上创建的索引。删除聚集索引时,表上的所有非聚集索引都将被重建。
只有表的所有者可以删除其索引,所有者无法将该权限转让给其他用户。
五. 视图
1. 单表视图
创建一个名为 CJ_BK_VIEW 的视图,该视图中包含不及格学生的学号、姓名、课程名,成绩和所在的班级名信息。
CREATE VIEW CJ_BK_VIEW
AS
SELECT 学号, 姓名, 课程名, 成绩, 班级名
FROM 学生基本信息
WHERE 成绩 < 60
GO
创建一个名为 JS_RK_VIEW 的视图,该视图中包含教师编号、姓名、课程名、学时、授课班级和学生数。
CREATE VIEW JS_RK_VIEW
AS
SELECT 教师编号, 姓名, 课程名, 学时, 授课班级, 学生数
FROM 教师信息, 学生基本信息
GO
创建一个名为 xs_07_view 的视图,该视图中只含有 “ 07 ” 系的学生基本信息。
CREATE VIEW xs_07_view
AS
SELECT *
FROM 学生基本信息
WHERE 系 = '07'
GO
2. 多表视图
创建描述学生成绩的视图 xs_cj_view,该视图中包含学号、姓名、性别、课程名和成绩等数据内容。
代码如下:
CREATE VIEW xs_cj_view
AS
SELECT 学生基本信息.学号, 姓名, 性别, 课程名, 成绩
FROM 学生基本信息, 选课, 课程
WHERE 学生基本信息.学号 = 选课.学号 AND 选课.课程号 = 课程.课程号
GO
本例创建的是基于学生基本信息表、选课表和课程表等三张表的视图,即多表视图。
3. 基于视图的视图
定义一个反映女生学习成绩的视图 Nxs_cj_view。
代码如下:
CREATE VIEW Nxs_cj_view
AS
SELECT *
FROM xs_cj_view
WHERE 性别 = '女'
GO
本例创建的是基于视图的视图。
假设我们已创建了描述所有学生学习成绩情况的视图,本例要的是女生的学习成绩情况。因此,可以通过 xs_ cj _view 视图来创建 Nxs_cj_view 视图,简化其操作。
4. 基于视图的操作
通过 CJ_BK_VIEW 视图查询补考的学生信息。
SELECT *
FROM CJ_BK_VIEW
WHERE 成绩 < 60 AND 成绩 > 35
GO
通过 07_NJ_VIEW 视图进行插入、修改和删除,数据由自己拟定。
插入
INSERT INTO 07_NJ_VIEW
VALUES('0201005', '张荣', '男', '1976-4-23', '副教授')
GO
修改
UPDATE 07_NJ_VIEW
SET 姓名 = '王一枚'
WHERE 姓名 = '王敏'
GO
删除
DELETE 07_NJ_VIEW
WHERE 性别 = '男'
GO
使用系统存储过程 sp_depends 查看 07_NJ_VIEW 视图的相关性。
Exec sp_depends 07_NJ_VIEW
5. 修改视图
使用 ALTER VIEW 语句修改视图,使 CJ_BK_VIEW 为加密视图。
ALTER VIEW CJ_BK_VIEW
WITH ENCRYPTION
将 07_NJ_VIEW 视图重命名为 NEW_VIEW。
EXEC sp_rename '07_NJ_VIEW ', 'NEW_VIEW'
6. 删除视图
删除 CJ_BK_VIEW 视图。
DROP VIEW CJ_BK_VIEW
六. 存储过程应用
1. 创建并执行存储过程
在 STUMS 数据库中,创建查询学生成绩的存储过程 xs_cj_proc。
代码如下:
USE STUMS
GO
CREATE PROC xs_cj_proc
AS
SELECT 学生基本信息.学号, 姓名, 课程名, 成绩
FROM 学生基本信息 JOIN 选课 ON 学生基本信息.学号 = 选课.学号
JOIN 课程 ON 选课.课程号 = 课程.课程号
在查询分析器中执行 xs_cj_proc 存储过程。
代码如下:
EXEC xs_cj_proc
GO
2. 带参数的存储过程
在 STUMS 数据库中,创建一个名为 XIBU_INFO_PROC 的存储过程,它带有一个输入参数,用于接受系部代码,显示该系的系部名称、系主任和联系电话。
代码如下:
USE STUMS
GO
CREATE PROCEDURE XIBU_INFO_PROC
@XBDM CHAR(2)
AS
SELECT 系部名称,系主任,联系电话
FROM 系部
WHERE 系部代码 = @XBDM
执行 XIBU_INFO_PROC 存储过程,查询系部代码为 03 的系部信息。
代码如下:
EXEC XIBU_INFO_PROC '03'
GO
在 STUMS 数据库中,创建一个名为 KC_INS_PROC 的存储过程,执行该存储过程将完成向课程表插入一条记录,新记录的值由参数提供。
代码如下:
USE STUMS
GO
CREATE PROCEDURE KC_INS_PROC
@KCH char(4),
@KCM varchar(20),
@KCXZ char(1),
@XF tinyint
AS
INSERT 课程 VALUES(@KCH,@KCM,@KCXZ,@XF)
执行 KC_INS_PROC 存储过程,完成向课程表中插入一数据行( ’ 0303 ’ , ’ VB程序设计 ’ , ’ A ’ , 5 )
代码如下:
EXEC KC_INS_PROC '0303','VB程序设计','A',5
GO
3. 创建并执行带有通配符参数的存储过程
在 STUMS 数据库中,创建一个名为 JS_CX_PROC 的存储过程,执行该存储过程,查询教师表中同姓的老师信息。
代码如下:
USE STUMS
GO
CREATE PROCEDURE JS_CX_PROC
@XM VARCHAR(8) = '_%'
AS
SELECT *
FROM 教师
WHERE 姓名 LIKE @XM
GO
执行 JS_CX_PROC 存储过程,查询所有姓王的教师信息。
代码如下:
EXEC JS_CX_PROC '王%'
GO
4. 创建并执行带有输出参数的存储过程
在 STUMS 数据库中,创建一个存储过程 tj_nopass_num 统计未通过考试的学生人数。
代码如下:
USE STUMS
GO
CREATE PROCEDURE tj_nopass_num
@count int OUTPUT
AS
SELECT @count = COUNT(*)
FROM 选课
WHERE 成绩 < 60
GO
执行 tj_nopass_num 存储过程,统计考试不及格的人数。
代码如下:
DECLARE @tj int /*定义变量*/
EXEC tj_nopass_num @tj OUTPUT
PRINT @tj /*在屏幕上显示统计结果*/
GO
☆ 需要强调的是,执行带有输出参数的存储过程,需定义一个变量接受输出参数这回的值,而且在该变量后面也需要跟随 OUTPUT 关键字。
在 STUMS 数据库中,创建一个存储过程 js_xl_tj_proc,其功能是从 “ 教师 ” 表中根据输入的学历名称,统计出相应的人数。
这是要创建带有一个输入参数和输出参数的存储过程。
代码如下:
USE STUMS
GO
CREATE PROCEDURE js_xl_tj_proc
@xl char(8), /*定义输入参数*/
@rs int OUTPUT /*定义输出参数*/
AS
BEGIN
select @rs = count(*)
from 教师
where 学历 = @xl
GROUP BY 学历
END
GO
执行 js_xl_tj _proc 存储过程,统计教师表中 “ 大学本科 ” 的人数。
代码如下:
DECLARE @xl char(8), @rs int
SET @x = '大学本科'
EXEC js_xl_tj_proc @xl, @rs OUTPUT
PRINT @xl + STR(@rs) + '人'
GO
5. 存储过程的重编译处理
1 在建立存储过程时设定重编译其语法格式如下:
CREAT PROCEDURE procedure_name
WITH RECOMPILE
AS sql_statement
2 在执行存储过程时设定重编译其语法格式如下:
EXECTUE procedure_name WITH RECOMPILE
3 通过使用系统存储过程设定重新编译其语法格式如下:
EXEC sp_recompile procedure_name
利用 sp_recompile 命令为存储过程 xs_cj_proc 设定重编译标记。
EXEC sp_recompile xs_cj_proc
运行后提示:已成功地将对象 xs_cj _proc 标记为重新编译。
6. 查看存储过程
使用系统存储过程 sp_helptext 查看存储过程的源代码
语法如下:
EXEC sp_helptext procedure_name
其中,
procedure_name 为用户需要查看的存储过程名称。
利用 sp_ helptext 存储过程查看 KC_INS_PROC 的源代码。
代码:
EXEC sp_ helptext KC_INS_PROC
使用 sp_ help 、sp_depends 和sp_stored_procedures 查看 xs_cj_proc 存储过程的相关信息。
代码如下:
EXEC sp_ help xs_cj_proc --查看存储过程的参数、类型等一般信息
EXEC sp_depends xs_cj_proc --查看存储过程的依赖关系及列引用等相关性信息
EXEC sp_stored_procedures xs_cj_proc --查看当前数据库中的存储过程列表
7. 修改存储过程
使用 ALTER PROCEDURE 语句修改存储过程
修改存储过程 xs_cj_proc,查询课程成绩不及格的学生的学号、姓名、课程名和成绩。
代码如下:
USE STUMS
GO
ALTER PROC xs_cj_proc
AS
SELECT 学生基本信息.学号, 姓名, 课程名,成绩
FROM 学生基本信息 JOIN 选课 ON 学生基本信息.学号=选课.学号
JOIN 课程 ON 选课.课程号 = 课程.课程号
WHERE 成绩 < 60
GO
8. 删除存储过程
DROP PROCEDURE 语句可以一次从当前数据库中将一个或多个存储过程或过程组删除,其语法格式如下:
DROP PROCEDURE 存储过程名[,…n]
删除存储过程 xs_cj_proc
代码如下:
DROP PROCEDURE xs_cj_proc
GO