数据文件
SQL Server 数据库具有以下3种类型的文件。
数据文件:用来存放数据,
(1)主数据文件
一个数据库必须有且只有一个主数据文件,其扩展名为.mdf
(2)次数据文件
一个数据库可以没有也可以有多个次数据文件,其扩展名为.ndf
(3)事务日志文件(.ldf )
日志文件为数据库的恢复提供日志信息。每个数据库至少包含一个日志文件,也可以有多个。日志文件的扩展名建议为.ldf。
数据库文件组
出于分配和管理的目的,可以将数据库文件分成不同的文件组。每个文件组有一个组名。文件组分主文件组和次文件组。
(1)主文件组
主文件组包含主数据文件和任何没有明确指派给其它文件组的其它文件。
(2)用户定义文件组(次文件组)
用户定义文件组是在 create database 或 alter database 语句中,使用 FILEGROUP 关键字指定的文件组。
一个文件只能属于一个文件组,一个文件组也只能被一个数据库使用。
事务日志
事务日志是一个与数据库文件分开的文件。它存储对数据库进行的所有更改,并记录全部插入、更新、删除、提交、回退和数据库模式变化。
事务日志是任何数据库的关键组成部分,是备份和恢复的重要组件,如果系统出现故障,它将成为最新数据的重要来源。
在默认的情况下,所有数据库都使用事务日志。事务日志的使用是可选的,但是,除非您因特殊原因而不使用,否则您应始终使用它。运行带有事务日志的数据库可提供更强的故障保护功能、更好的性能以及数据复制功能。
数据库快照
SQL Server 包含master、model、msdb和tempdb4个系统数据库
(1)Master数据库
系统最重要的数据库,记录了所有系统信息。如所有的
登录信息、系统设置信息、SQL Server的初始化信息和其它
系统数据库及用户数据库的相关信息。
(2)Model数据库
是模板数据库,为新建立的数据库提供模板和原型。
(3)Tempdb数据库
是一个临时数据库,它为所有的临时表、临时存储过程及其它临时操作提供存储空间。
(4)Msdb数据库
是代理服务数据库,为其警报、任务调度和记录操作员的操作提供存储空间。
建立数据库
(1)使用对象资源管理器建立数据库
(2)使用T-SQL命令建立数据库
建立数据库的最简方法
CREATE DATABASE database_name
建立数据库的完整语法
CREATE DATABASE database_name
[ ON [ PRIMARY ]
[<filespec> [,…n] ]
]
[ LOG ON { <filespec> [,…n] } ]
其中filespec在实际应用中用下面相应代码替换:
<filespec>::=
([ NAME=logical_file_name,]
FILENAME=‘os_file_name’
[,SIZE=size]
[,MAXSIZE={max_size|UNLIMITED}]
[,FILEGROWTH=growth_increment] )
例子:
CREATE DATABASE score3
ON PRIMARY
( NAME=score3_data,
FILENAME='D:\sql\score3_data.mdf’,
SIZE=5MB,
MAXSIZE=20MB,
FILEGROWTH=10%
),
( NAME=score3_data1,
FILENAME=’ D:\sql\score3_data1.ndf’,
SIZE=2MB,
MAXSIZE=5MB,
FILEGROWTH=1MB
) LOG ON
( NAME=score3_log,
FILENAME=’ D:\sql\score3_log.ldf’,
SIZE=2MB,
MAXSIZE=UNLIMITED,
FILEGROWTH=1MB )
修改和删除数据库
使用对象资源管理器修改数据库
使用T-SQL命令修改数据库
alter database database_name
{ADD FILE<filespec>[,…n]
|ADD LOG FILE <filespec> [,…n]
|ADD FILEGROUP group_name
|REMOVE FILE logical_file_name
|REMOVE FILEGROUP group_name
|MODIFY FILE <filespec>
|MODIFY NAME=new_databasename
|MODIFY FILEGROUP group_name
NAME=new_groupname }
Database_name:要修改的数据库的名称。
ADD FILE<filespec>[,…n]:添加数据文件。
ADD LOG FILE <filespec> [,…n]:添加日志文件。
ADD FILEGROUP group_name:添加文件组。
REMOVE FILE logical_file_name:删除文件,是物理删除。
REMOVE FILEGROUP group_name:删除文件组。
MODIFY FILE <filespec>:修改数据库文件。
MODIFY NAME=new_databasename:重命名数据库。
注意点:
修改文件属性时,不需指定物理文件名。
文件大小不能小于初始容量。
删除文件组前必须保证该文件组为空,若其中有文件则应先删除 。
SQL Server的数据类型是SQL Server预先定义好的,可以直接使
用。SQL Server提供以下系统数据类型。
(1)bit
状态类型,可以取值为1或0。
(2)整型
(1)bigint(长整型):8个字节
(2)int(基本整型):4个字节
(3)Smallint (短整型):2个字节
(4)Tinyint(微整型) :1个字节 ,表示无符号整数,其取值范围0~255.
(3)精确数值型
包括decimal和numeric两种类型,该数值型数据由整数部分和小数部分组成,存储数值的范围为-10e38+1~10e38-1。
格式:
decimal(p,[s])或者numeric(p,[s])
其中:p(有效位数,小数点左右两侧位数之和)
s(小数位数),s默认值为0,0<=s<=p
例:decimal(10,6)
表示数中共有10位数,基中整数占4位,小数占6位。
decimal和numeric功能等价
(4)近似数据类型
用科学计数法来表示浮点数的数据类型。浮点数为近似值,包括re
al和float两种类型。两者的区别和能表示的数值范围如表所示。
数据类型 | 数据范围 | 占用存储空间 |
---|---|---|
real | -3.40E+38~3.40E+38 | 4个字节 |
float | -1.79E+308~1.79E+308 | 8个字节 |
real:精确到7位小数
float:可以精确到第15位小数,默认占用8个字节的存储空间。Float数据类型也可以写为float(n)的形式,n为1到15之间的整数值。当n取1到7时,系统用4个字节存储它;当n取8到15时,用8个字节存储它。
(5)字符数据类型
字符型数据是指由字母、数字和其他一些特殊符号(如$,@)构成的字符串。在引用字符串时要用单引号括起来。字符型包括char、varchar、nchar和nvarchar四种类型。
1)char(n)
存放固定长度的n个字符数据。若输入字符长度不足n时,则用空格补足。1≤n≤8000。
2)varchar(n)
存放可变长度的n个字符数据。若输入字符长度不足n时,则按实际输入长度存储。1≤n≤8000。
3)nchar[(n)] :可存储1~4000个定长Unicode字符串,字符串长度在创建时指定;如未指定,默认为nchar(1)。每个字符占用2bytes存储空间。
4)nvarchar[(n)] :可存储最大值为4000个字符可变长Unicode字符串。可变长Unicode字符串的最大长度在创建时指定,如nvarchar(50),每个字符占用2bytes存储空间。
(6)货币型(低版本的类型)
用十进制数来表示货币值。使用货币型数据时必须在数据前加上货币符号($),当货币值为负数时,在符号和数据之间加负号,如:$123,$-231
。
包括money和smallmoney两种类型。
数据类型 | 数据范围 | 占用存储空间 |
---|---|---|
money | -2E+63~2E+63-1 | 8个字节 |
smallmoney | -2E+31~2E+31-1 | 4个字节 |
(7)文本型
当存储的字符数目大于8000时使用文本型,文本型包括text和ntext两种。
text:用来存储ASCLL编码字符数据,最多可以存储231-1(约20亿)个字符。在定义Text数据类型时,不需要指定数据长度.
ntext:用来存储Unicode编码字符型数据,最多可能存储230 -1(约10亿)个字符,其存储长度为实际字符个数的两倍,因为Unicode字符用双字节表示。
(8)日期型
旧类型:包括smalldatetime和datetime。
日期型数据以字符的形式表示,即要用单引号括起来。
数据类型 | 日期范围 | 占用存储空间 |
---|---|---|
smalldatetime | 1900年1月1日—2079年6月6日 | 4个字节 |
datetime | 1753年1月1日—9999年12月31日 | 8个字节 |
(9)table数据类型
table数据类型是一种特殊的数据类型,用于存储结果集以进行后续处理。
(10)二进制数据类型
binary[(n)]:存放n字节固定长度的二进制数据。1≤n≤8000。
varbinary[(n)]:存放n字节可变长度的二进制数据,
1≤n≤8000。
(11)自定义数据类型
使用sp_addtype创建用户自定义数据类型的语法如下:
sp_addtype[@typename=]type,
[@phystype=]system_data_type
[,[@nulltype=]'null_type']
参数说明:
①[@typename=]type:
指定创建的用户自定义数据类型的名称。
用户自定义数据类型名称必须遵循标识符的命名规则,而且在数据库中唯一。
②[@phystype=]system_data_type:
指定用户自定义数据类型所依赖的系统数据类型。
③[@nulltype=]‘null_type’:指定用户自定义数据类型的可空属性,
即用户自定义数据类型处理空值的方式。取值为“NULL”,“NOT NULL”或“NONULL”。
例 在score数据库中,创建名为“sex_type”自定义数据类型,依赖字符型数据,宽度为2,不允许为空。
USE score
EXEC sp_addtype sex_type,'char(5)', 'not null'
可以像使用系统数据类型一样使用自定义数据类型。
例 在score数据库的student表中的sex字段的数据类型修改为sex_type。
USE score
ALTER TABLE student
ALTER COLUMN sex sex_type
删除自定义数据类型
使用sp_droptype删除用户定义数据类型的语法如下:
Sp_droptype {‘类型名’}
例 把score数据库中student表的sex字段的数据类型修改为char(2),然后再删除自定义数据类型sex_type。
USE score
ALTER TABLE student
ALTER COLUMN sex char(2)
GO
EXEC sp_droptype sex_type
注意:当自定义数据类型被使用状态下不能被删除
(1)建立表
使用对象资源管理器建立表
使用T-SQL语句建立表
CREATE TABLE <table_name>
( 列名 数据类型 [NOT NULL /NULL] [IDENTITY(初始值,步长值)] [DEFAULT<默认值> ]
[,…n]
[,UNIQUE (列名[,…n])]
[,PRIMARY KEY(列名[,…n])]
[,FOREIGN KEY(列名) REFERENCES table_name [(列名)]
[,CHECK(条件)])
说明
列名:用户自定义属性的名称,应遵守标识符的命名规则。
数据类型:用来指定该列存放何种类型的数据。
NOT NULL | NULL:指定该列是否允许存放空值。
IDENTITY(初始值,步长值):用来指定标识列及其初始值和步长值。
UNIQUE:指定唯一性约束。
PRIMARY KEY:建立主键约束;
FOREIGN KEY:建立外键约束,括号中所指定的列即为外键; REFERENCES用来指定外键所参照的表,表名后面的列名用来指定外键所参照的列。
DEFAULT:为指定的列定义一个默认值,当该列没有录入数据时,则用默认值代替。
CHECK:定义检查约束,使用指定条件对存入表中的数据进行检查,以确定其合法性,提高数据的安全性。
例 在score数据库中建立一个名为teach的教师任教表,
并定义主键约束和外键约束。
Use score
Go
CREATE TABLE teach
( teacher_id char(4) NOT NULL,
course_id char(5) NOT NULL,
primary key(teacher_id,course_id),
FOREIGN KEY(teacher_id) REFERENCES teacher(teacher_id),
FOREIGN KEY(course_id) REFERENCES course(course_id)
)
例 在score数据库中建立一个名为course的课程信息表,
并定义主键约束和课程名称字段的唯一性约束。
USE score
GO
CREATE TABLE course
( course_id char(5) PRIMARY KEY,
course_name char(20) ,
period int,
UNIQUE(course_name)
)
(2)修改表
使用对象资源管理器修改表
使用ALTER TABLE 语句修改表结构
ALTER TABLE table_name
{
ALTER COLUMN 字段名 数据类型 [NULL|NOT NULL]
|ADD 字段名 数据类型 [NULL|NOT NULL]
|ADD CONSTRAINT 约束名 约束类型
|DROP COLUMN 字段名 [,…n]
|DROP CONSTRAINT 约束名
}
参数说明:
(1)ALTER TABLE:表明是要修改表
(2)table_name:被修改的表名
(3)ALTER COLUMN 列名:表明要更改的字段
(4)ADD 列名:添加新的字段
(5)DROP COLUMN 列名:删除指定的列
(6)DROP CONSTRAINT子句:用来删除指定的约束
(7)ADD CONSTRAINT:为表添加约束。各类型约束格式如下:
1)添加主键约束
ADD CONSTRAINT 约束名 PRIMARY KEY(列名[,…n])
2)添加外键约束
ADD CONSTRAINT约束名FOREIGN KEY(列名) REFERENCES table_name(列名)
3)添加默认值约束
ADD CONSTRAINT 约束名 DEFAULT <默认值> FOR <列名>
4)添加唯一性约束
ADD CONSTRAINT 约束名 UNIQUE(列名[,…n])
5)添加检查约束
ADD CONSTRAINT 约束名 CHECK(检查条件)
例 为score数据库中的course表添加课程类型字段,字段名为
c_type。
USE score
GO
ALTER TABLE course
ADD c_type char(12)
例 为score数据库中的class表添加主键约束,指定class_id字段为主键。
USE score
GO
ALTER TABLE class
ADD CONSTRAINT PK_id PRIMARY KEY(class_id)
(3)删除表
使用对象资源管理器删除表
使用T-SQL语句删除表
语法格式如下:
DROP TABLE table_name
参数说明:
DROP TABLE:指明要删除的对象是表。
table_name:指定要删除表的名称。
(1)插入记录
使用对象资源管理器添加记录
使用INSERT语句添加记录
语法:
INSERT [ INTO] <表名>[(<字段名1>[,<字段名2>…])]
VALUES(<常量1>[,<常量2>]…
语法说明:
(1 )[(<字段名1>[,<字段名2>…])] :要插入字段值的字段名
省略即表示所有列都要插入数据。
(2) (<常量1>[,<常量2>]…):要插入的字段值,与上面字段名一一对应。
例 使用INSERT语句往class表中录入记录。
方法一:
INSERT class(class_id , class_name, dept_id)
VALUES(‘20170101', '17计算机软件1班','01')
方法二:
INSERT class
VALUES(‘20170102', '17计算机软件2班','01')
说明:
①INSERT语句一次只能插入一条记录,如果想插入多条,需用逗号隔开。
②INTO 可以省略。
③当往表中所有列都录入数据并且指定数据的顺序与表结构中列的顺序一致时,则可以省略列名列表,如方法二;也可以指明所有列,如方法一。若只往指定的表中部分列录入数据,那么列名列表不能省略。
(2)修改记录
使用对象资源管理器添加记录
使用update语句修改记录
语法:
UPDATE <表名>
SET <字段名>=<表达式>[,......n]
[WHERE <条件>]
功能:
修改指定表中满足WHERE子句条件的记录。其中SET子句给出<表达式>的值用于取代相应的属性列值,如果WHERE省略,表示修改所有记录。
例 将姓名为张丹丹的address修改为广东广州
UPDATE student
SET address=’广东广州’
WHERE student_name=’张丹丹’
(3)删除记录
使用对象资源管理器删除记录
使用DELETE 语句删除记录
语法:
DELETE [FROM]<表名>[WHERE<条件>]
功能:删除表中满足条件的记录,省略WHERE表示删除所有记录。
SQL的全称为Structured Query Language(结构化查询语言)。它是数据库系统的通用语言,利用它,用户可以用几乎同样的语句在不同的数据库系统上执行同样的操作。
SQL语言是一个综合的,功能强大又简单易学的语言,它集数据查询、数据操纵、数据定义和数据控制于一体。SQL语言按照功能可以分为4大类。
(1)数据查询语言(Data Query Language,DQL)
按照指定的组合、条件表达式或排序检索已存在的数据库中的数据,但并不改变数据库中数据。命令动词有SELECT。
(2)数据定义语言(DDL:Data Definition Language)
创建、修改或删除数据库中各种对象,包括表、视图、索
引等。命令动词有CREATE、DROP、ALTER。
操 作 对 象 | 操 作 方 式 | ||
---|---|---|---|
命令 | 创 建 | 修改 | 删除 |
表 | CREATE TABLE | ALTER TABLE | DROP TABLE |
视图 | CREATE VIEW | DROP VIEW | |
索引 | CREATE INDEX | DROP INDEX |
(3)数据操纵语言(Data Manipulation Language,DML)
对已经存在的数据库进行记录的插入、删除、修改等操作。命令动词有INSERT、UPADATE、DELETE。
(4)数据控制语言(Data Control Language,DCL)
用来授予或收回访问数据库的某种特权、控制数据操纵事务的发生时间及效果、对数据库进行监视。命令动词有GRANT、REMOVE等。
数据查询,也叫数据检索。是指针对数据库中的数据按指定的条件和特定的组合进行对数据表的检索。
(1)SELECT查询
基本格式是:
SELECT <字段列表>
FROM 〈表名〉
[WHERE 〈查询条件〉]
含义是:根据WHERE子句的查询条件,从FROM子句指定的表中找出满足条件记录,再按SELECT语句中指定的字段次序,筛选出记录中的指定字段值。若不设置查询条件,则表示被查询的表中所有记录都满足条件。
完整格式是:
SELECT [ALL|DISTINCT]<字段列表>
[INTO 新表名]
FROM <表名列表>
[WHERE <查询条件>]
[GROUP BY <字段名>[HAVING <条件表达式>]]
[ORDER BY <字段名>[ASC|DESC]]
参数说明:
(1)ALL|DISTINCT
其中ALL表示查询满足条件的所有行;DISTINCT表示在查询的结果集中,消除重复的记录。
(2)<字段列表>:由被查询的表中的字段或表达式组成,指明要查询的字段信息。
(3)INTO 新表名
表示在查询的时候同时建立一个新的表,新表中存放的数据来源于查询的结果。
(4)FROM <表名列表>
指出针对那些表进行查询操作,可以是单个表,也可以是多个表,表名与表名之间用逗号隔开。
(5)WHERE <查询条件>
用于指定查询的条件。该项是可选项,即可以不设置查询条件,但也可以设置一个或多个查询条件。
(6)GROUP BY <字段名>
对查询的结果按照指定的字段进行分组。
(7)HAVING <条件表达式>:
对分组后的查询结果再次设置筛选条件,最后的结果集中只包含满足条件的分组。必须与GROUP BY子句一起使用。
(8)ORDER BY <字段名>[ASC|DESC]
对查询的结果按照指定的字段进行排序,其中[ASC|DESC]用来指明排序的方式。ASC为升序;DESC为降序。
整个SELECT语句的含义:
根据WHERE子句的筛选条件,从FROM子句指定的表中找出满足条件记录,再按SELECT语句中指定的字段次序,筛选出记录中的字段值构造一个显示结果表。
如果有GROUP BY子句,则将结果按group by后面的“字段名”的值进行分组,该字段中值相等的元组为一个组;
如果GROUP BY子句带有短语HAVING,则只有满足短语指定条件的分组才会输出。
如果有ORDER BY子句,则结果表要按照order by后面的<字段名>的值进行升序和降序排列。
SELECT [ALL|DISTINCT]<目标列表达式>实现的是对表的投影操作,WHERE <条件表达式>中实现的是选择操作。
(2)针对单表的查询
1)查询指定的字段
用户往往需要了解表中部分字段信息或者全部字段信息,通过对SELECT语句中“字段列表”的控制即可满足用户的需求。
查询部分字段
例 查询student表中学生的学号、姓名以及家庭住址。
SELECT student_id, student_name, address
FROM student
查询全部字段
方法一:列举法,即把表中所有字段在SELECT子句中的“字段列表”中列举出来;
方法二:通配符法,即使用通配符“*”来代替表中所有的字段。
例 查询student表中所有学生的所有字段信息。
方法一:列举法
SELECT student_id, student_name, class_id, sex,
born_date, address, tel, resume
FROM student
方法二:通配符法
SELECT *
FROM student
2)查询满足条件的记录
当用户只需要了解表中部分记录的信息时,这就应该在查询的时候使用WHERE子句设置筛选条件,把满足筛选条件的记录查询出来。
设置查询条件的SELECT查询语句基本格式是:
SELECT <字段列表>
FROM 〈表名〉
WHERE 〈查询条件〉
查询条件可以是关系表达式、逻辑表达式和特殊表达式。
关系表达式
用关系运算符号将两个表达式连接在一起的式子称为关系表达式,其返回值为逻辑真(TRUE)或逻辑假(FALSE),关系表达式的格式为:
<表达式1><关系运算符><表达式2>
常用的关系运算符如下表所示。
运算符号 | 含义 |
---|---|
= | 等于 |
< | 小于 |
<= | 小于等于 |
> | 大于 |
>= | 大于等于 |
!=或<> | 不等于 |
例 查询所有男学生的学号、姓名、性别和出生日期。
SELECT student_id, student_name, sex, born_date
FROM student
WHERE sex=’男’
逻辑表达式
用逻辑运算符号将两个表达式连接在一起的式子称为逻辑表达式,其返回值为逻辑真(TRUE)或逻辑假(FALSE),逻辑表达式的格式为:
[<关系表达式1>]<逻辑运算符><关系表达式2>
常用的逻辑运算符如下表所示。
运算符号 | 含义 |
---|---|
OR | 逻辑或 |
AND | 逻辑与 |
NOT | 逻辑否 |
特殊表达式
特殊表达式在比较运算中有一些特殊的作用。常用的特殊运算符号如下表所示。
运算符号 | 含义 |
---|---|
% | 通配符,包含0个或多个字符的任意字符串 |
— | 通配符,表示任意单个字符 |
[ ] | 指定范围或集合中的任意单个字符 |
BETWEEN…AND | 定义一个区间范围 |
IS [NOT] NULL | 检测字段值为空或不为空 |
LIKE | 字符匹配操作符 |
[NOT ] IN | 检查一个字段值属于或不属于一个集合 |
EXISTS | 检查某一字段是否存在值 |
字符匹配操作符——LIKE
LIKE关键字的作用是用于指出一个字符串是否与指定的字符串相匹配,其运算对象可以是char、text、datetime等数据类型,返回逻辑值。LIKE表达式的格式为:
字符表达式1 [NOT] LIKE 字符表达式2
(字段名) (值)
若省略NOT,则表示字符表达式1与字符表达式2相匹配时才返回逻辑真。
若选择NOT,则表示字符表达式1与字符表达式2不匹配时才返回逻辑真。
说明:在例用通配符“%”或“-”时,只能用字符匹配操作符LIKE
不能使用“=”运算符,反之,如果匹配的字符串中不包含通配符
,则可以用“=”代替LIKE。
例 查询姓刘的学生的基本情况。
SELECT *
FROM student
WHERE student_name LIKE ‘刘%’
例 查询所有姓张和姓刘学生的基本情况。
SELECT *
FROM student
WHERE student_name LIKE ‘[张,刘]%’
区间控制运算符——BETWEEN…AND
判断所指定的值是否在给定的区间,返回逻辑值。格式为:
表达式 [NOT] BETWEEN 表达式1 AND 表达式2
(字段名) (下限) (上限)
“表达式1”是区间的下限,“表达式2”是区间的上限。
若省略NOT,则表示表达式的值在指定的区间内即返回逻辑真。
若选择NOT,则表示表达式的值不在指定的区间内即返回逻辑真。
例 查询出1998年1月1日至1999年12月31日出生的学生的学号、姓名、出生日期。
SELECT student_id, student_name, born_date
FROM student
WHERE born_date BETWEEN '1998-1-1' AND '1999-12-31'
空值判断运算符——IS NULL
IS NULL用来测试字段值是否为空值,返回逻辑值,格式为:
表达式 IS [NOT] NULL
若省略NOT,则表示表达式的值为空时即返回逻辑真。
若选择NOT,则表示表达式的值不为空时即返回逻辑真。
例 查询备注内容为空的学生的学号、姓名与备注。
SELECT student_id, student_name,resume
FROM student
WHERE resume is null
集合判断运算符——IN
判断表达式的值是否属于某一个给定的集合。返回逻辑值,格式为:
表达式 [NOT] IN (表达式1 [,…n])
(字段名) (字段值,...)
若省略NOT,则表示表达式的值属于给定集合时即返回逻辑真。
若选择NOT,则表示表达式的值不属于给定的集合时即返回逻辑真。
例 查询来自广东广州和湖南长沙学生的姓名、班级编号和来自的城市。
SELECT student_name, class_id,address
FROM student
WHERE address in (‘广东广州’,’湖南长沙’)
3)对查询结果进行编辑
对查询的字段进行说明
在SELECT语句中,可以在一个字段的前面加上一个单引号字符串,对后面的字段起说明作用。
例 查询学生表中学生的姓名和来自的城市,并分别用中文对其进行说明。
SELECT '姓名', student_name, '城市', address
FROM student
对查询的字段使用别名
为了能让人更容易了解字段的内容,可以为字段指定别名,并显示在结果集中,方法有3种:
方法一:字段名 AS 别名;
方法二:字段名 别名
方法三:别名=字段名
例 查询学生表中的学生的student_name和born_date信息,并用中文“姓名”和“出生日期”来显示字段名。
SELECT student_name AS 姓名,
born_date AS 出生日期
FROM student
显示表达式的值
SELECT子句后面可以是字段名,也可以是表达式。
例 查询学生表中所有女学生的姓名和年龄。
SELECT student_name ,
year(getdate())-year(born_date) as 年龄
FROM student
WHERE sex='女'
消除结果集中重复的记录
SELECT子句中有一个可选项:ALL|DISTINCT,其中DISTINCT的作用就是用来消除结果集中重复的记录,内容相同的记录只显示一条。
例 查询学生表学生所来自的城市。
SELECT DISTINCT address
FROM student
返回指定的行数
查询语句中还可以指定表中返回的行数,格式如下:
SELECT [TOP n] 字段列表
FROM <表名>
其中,TOP n用于指定查询结果返回的行数,其返回的结果一定从上往下的n行信息。
例 查询学生表前3位学生的学号和姓名。
SELECT TOP 3 student_id, student_name, class_id
FROM student
聚合函数
SQL SERVER提供的聚合函数,用来完成一定的统计功能.能对集合中的一组数据进行计算,并返回单个计算结果.常与SELECT和GROUP BY 子句一起使用.
函数 | 功能 | 含义说明 |
---|---|---|
COUNT | 统计 | 统计满足条件的记录数 |
MAX | 求最大值 | 求某一集合中的最大值 |
AVG | 求平均值 | 计算某一数值集合中的平均值 |
SUM | 求和 | 计算某一数值集合中的总和 |
MAX和MIN函数
MAX和MIN函数分别用于查找指定集合中的最大值和最小值。格式为:
MAX/MIN([ALL | DISTINCT] 表达式)
(字段名)
其中,ALL表示对所有值进行聚合函数运算,DISTINCT表示如果有多个重复的值,则这些重复值只计算一次,默认为ALL。表达式可以是涉及一个列或多个列的算术表达式。
例 查找成绩表中1001号课程的最高分和最低分。
SELECT max(grade) as 最高分 , min(grade) as 最低分
FROM score
WHERE course_id='1001'
SUM函数
该函数用于计算查询到的数据值的总和。语法格式为:
SUM([ALL | DISTINCT] 表达式)
(字段名)
例 计算2017010101号学生总成绩。
SELECT sum(grade) as 总分
FROM score
WHERE student_id=‘2017010101'
AVG函数
用于计算查询结果的平均值。语法格式为:
AVG([ALL | DISTINCT] 表达式)
(字段名)
例 计算2017010101号学生平均成绩。
SELECT AVG(grade) as 平均分
FROM score
WHERE student_id=‘2017010101'
COUNT函数
用于统计查询结果集中记录的数目。语法格式为:
COUNT([ALL | DISTINCT] 表达式)
(字段名)
如果COUNT函数使用字段名做为参数,则只统计内容不为空的行的数目。
如果执行COUNT(),即使用“”作为参数,则统计所有行(包括空值的行)。
例 统计学生表中学生的总数。
SELECT COUNT(student_id) as 学生总数
FROM student
对查询结果进行分组和筛选
GROUP BY子句将查询结果表按某一列或多列值分组,值相等
的为一组。一般与SQL的聚合函数一起使用,对分组后的每一组数据分别进行统计。
格式:
SELECT <[字段列表],[聚合函数(字段名)]>
FROM <表名>
GROUP BY <字段列表>
[HAVING <条件表达式>]
例 统计各个班学生的总人数。
SELECT class_id , count(student_id)
FROM student
GROUP BY class_id
对查询结果集进行排序
在SELECT查询语句中。使用ORDER BY子句对查询输出结果进行排序。
排序的方式有两种:ASC(升序)和DESC(降序)。
例 统计成绩表中每个学生的总分和平均分,把查询结果按总分的降序排列输出。
SELECT student_id , sum(grade) as 总分,
avg(grade) as 平均分
FROM grade
GROUP BY student_id
ORDER BY 总分 DESC
把查询结果插入新的表
通过INTO子句,可以创建一个新表并将查询到的结果插入到新表中。
例 查询学生表中学生的学号、姓名和班级编号,并把查询结果插入到新的表student_class中。然后针对student_class表进行查询操作,验证新表student_class是否建立成功且被插入了记录。
SELECT student_id, student_name, class_id
INTO student_class
FROM student
说明:新表的所包含的字段与数据类型与SELECT语句的字段列表一致。如果要创建的临时表,则只要在表名前加上“#或##”即可
多表连接查询
连接查询分两大类,一是使用连接谓词进行连接;二是使用关键字JOIN进行连接。
连接谓词
使用连接谓词连接表的基本格式为:
SELECT <输出字段列表>
FROM 表1,表2 [,...n]
WHERE <表1.字段名1> <连接谓词> <表2.字段名2>
连接字段:必须是可比较的
连接谓词包括:=、<、<=、>、>=、!=、<>等,当比较符是=时称为等值连接。
等值连接和不等连接
当连接谓词是“=”时的连接,称为等值连接。当连接谓词是不等运算符时的连接,称为不等连接。
例 查询学生的基本信息和成绩信息。
SELECT student.* , score.*
FROM student , score
WHERE student.student_id=score.student_id
自然连接
若在等值连接中把输出字段列表中重复的字段只保留一个的连接称为自然连接。
在针对多表进行查询时。如果所引用的列为被查询的表所共有,则引用列时必须用表名来指定列是来源于哪个表,指定方法为:表名.列名。反之,不一定需要表名来指定来源。
例 查询学生的基本信息和成绩信息,在输出结果中相同的字段只保留一个。
SELECT student.student_id, student_name,
class_id, sex, born_date,
address, tel, resume, course_id, grade
FROM student , score
WHERE student.student_id=score.student_id
复合条件连接
含有多个连接条件称为复合条件连接。
例 查询学生的学号、姓名、课程名称和成绩信息。
SELECT student.student_id,student_name,course_name,grade
FROM student, score, course
WHERE student.student_id=score.student_id
AND score.course_id=course.course_id
自连接
一个表与自身进行连接称为自连接。
在同一个表中查找具有相同字段值的行,则可以使用自连接。在使用自连接时需要为表指定两个别名,且对所有引用的列均要用别名来指定其来源。
例 查找同一课程成绩相同的学生的学号、课程号和成绩。
SELECT a.student_id,b.student_id,a.course_id,a.grade
FROM score a, score b
WHERE a.grade=b.grade
AND a.student_id<>b.student_id
AND a.course_id=b.course_id
以JOIN关键字连接
以JOIN关键字来连接表的方式,增强了表的连接能力和连接的灵活性。 使用JOIN关键字连接表的的基本格式为:
SELECT <输出字段列表>
FROM 表名1 <连接类型> 表名2 ON <连接条件>
[ <连接类型> 表名3 ON <连接条件>]......
参数说明:
1)表名1,表名2,表名3等用来指明需要连接的表。
2)连接类型有:[ INNER | { LEFT | RIGHE | FULL } OUTER ] JOIN。其中INNER JOIN表示内连接;OUTER JOIN表示外连接,外连接又分:左外连接(LEFT OUTER JOIN)、右外连接(RIGHT OUTER JOIN)和全外连接(FULL OUTER JOIN)。
3)ON:用来指明连接条件。
内连接(INNER JOIN)
等值连接、不等连接和自然连接属于内连接。以JOIN关键字来实现内连接——按照ON所指定的连接条件合并两个表,返回满足条件的行。
例 查询学生的基本信息和成绩信息
SELECT student.* , score.*
FROM student INNER JOIN score
ON student.student_id=score.student_id
外连接(OUTER JOIN)
外连接返回到查询结果集合中的不仅包含符合连接条件的行,而且还包括左表(左外连接时)、右表(右外连接时)或两个边接表(全外连接)中的所有数据行
左外连接
查询输出结果中显示符合条件的数据行及左边数据表中不符合条件的数据行。左外连接的连接格式为:
FROM 左表名 LEFT [OUTER] JOIN 右表名 ON 连接条件
例 查找所有学生的学号、姓名以及他们所学的课程编号和成绩,没有课程成绩的学生信息也要显示。
SELECT student.student_id, student_name,
course_id, grade
FROM student LEFT OUTER JOIN score
ON student.student_id=score.student_id
右外连接
查询输出结果中显示符合条件的数据行及右边数据表中不符合条件的数据行。右外连接的连接格式为:
FROM 左表名 RIGHT [OUTER] JOIN 右表名 ON 连接条件
例 查询学生的学号、所在的班级编号和班级名称,班级表中没有连接成功的记录也要显示。
SELECT student.student_id, class.class_id, class_name
FROM student RIGHT OUTER JOIN class
ON student.class_id=class.class_id
全外连接
查询输出结果中显示符合条件的数据行右边及左边数据表中不符合条件的数据行。全外连接的格式为:
FROM 左表名 FULL [OUTER] JOIN 右表名 ON 连接条件
例 查询学生的学号、所学课程名称及成绩,两表中没有连接成功的记录均要显示(采用全外连接)。
SELECT student_id, course_name, grade
FROM score FULL OUTER JOIN course
ON score.course_id=course.course_id
交叉连接
交叉连接也叫非限制连接,它将两个表不加任何约束地组合起来。在数学上,就是两个表的笛卡尔积。交叉连接后得到的结果集的行数是两个被连接表的行数的乘积。
例 查询学生的基本信息及其成绩信息(使用交叉连接)。
SELECT *
FROM student CROSS JOIN score
子查询
子查询是一个嵌套在 SELECT、INSERT、UPDATE 或 DELETE 语句中的WHERE 或 HAVING 子句内,或嵌套在其他子查询中的SELECT查询。
子查询可以嵌套,它能将比较复杂的查询分解为几个简单的查询。一个SELECT—FROM—WHERE语句称为一个查询块。将一个查询块嵌套在另一个WHERE子句或HAVING短语的条件中的查询称为嵌套查询。
SELECT class_name
外部查询 FROM class
WHERE class_id IN
( SELECT class_id
内部查询 FROM student
(子查询) WHERE student_name=‘张小云’
)
嵌套查询的执行顺序是:首先执行最底层的内部查询(即子查询),它的查询结果并不显示,而是传递给外层查询,用来做外部查询的查询条件。即按照由里向外的顺序执行。
子查询的使用
可以使用子查询的地方有:
●在使用 IN 或NOT IN的集合查询中。
●在UPDATE、DELETE和INSERT语句中。
●在使用比较运算符时
●使用 ANY 或 ALL时。
●使用 EXISTS或NOT EXISTS 引入的存在测试时。
●在有表达式的地方。
带谓词IN或NOT IN的子查询
IN子查询是把子查询的结果做为外部查询的条件。判断外部查询中的某个值是否属于子查询的结果集合。
格式:<表达式> [NOT] IN (子查询)
例 查找选修了1002号课程的学生的学号、姓名和班级编号。
SELECT student_id, student_name, class_id
FROM student
WHERE student_id IN
(SELECT student_id
FROM score
WHERE course_id=‘1002’)
带有比较运算符的子查询
当子查询返回的是单值时,子查询可以由一个比较运算符( =、<、<=、>、>=、!=或<>)引入。当子查询可能返回多个值时则应把比较运算符与ALL和ANY 结合使用。
格式为:表达式 { 比较运算符 } { ALL|ANY } (子查询)
ALL:表示表达式要与子查询的结果集中的所有值进行比较,当表达式与每个值都满足比较关系时,才返回TRUE,否则返回FALSE。
ANY:表示表达式只要与子查询的结果集中的某个值满足比较关系时,就返回TRUE,否则返回FALSE。
例 查询选修了1001号课程且成绩比0801103号学生1001号课程成绩高的学生的学号、课程编号和成绩。
SELECT student_id, course_id, grade
FROM score
WHERE course_id='1001'
AND grade>(SELECT grade
FROM score
WHERE student_id='0801103'
AND course_id='1001')
INSERT、DELETE和UPDATE语句中的子查询
子查询可以嵌套在INSERT、DELETE和UPDATE语句中,把子查询的结果插入到新表中或用来设置删除和修改记录的条件。
带子查询的插入操作
INSERT和SELECT语句结合起来,可以往指定的表中插入批量的记录。带子查询的插入操作的格式为:
INSERT [INTO] <表名>[(<字段1>[,<字段2>…])]
SELECT [(<字段A>[,<字段B>…])]
FROM <表名>
[WHERE<条件表达式>]
【例】创建一个新的学生表 st_info,要求:包含学号、姓名和备注三个字段,然后将student表中相应的字段值插入到表st_info中,最后显示st_info表中的记录。
CREATE TABLE st_info
( 学号char(10) PRIMARY KEY,
姓名 char(8),
备注 char(30) )
Go
INSERT INTO st_info(学号,姓名,备注)
SELECT student_id, student_name,resume
FROM student
Go
SELECT *
FROM st_info
带子查询的修改操作
子查询与UPDATE嵌套,子查询用来指定修改的条件。
【例】将20170101班学生1001号课程的成绩增加5分。
UPDATE score
SET grade=grade+5
WHERE student_id in
(SELECT student_id
FROM student
WHERE class_id=‘20170101')
带子查询的删除操作
子查询与DELETE嵌套,子查询用来指定删除的条件。
【例】删除没有选修1001号课程的学生记录。
DELETE student
WHERE student_id not in
(SELECT student_id
FROM score
WHERE
course_id='1001' )
相关子查询
允许引用外部查询中的任何表的子查询称为相关子查询
相关子查询在执行时,要使用到外部查询的数据。外部查询首先选择数据提供给子查询,然后子查询对数据进行比较,执行结束后再将查询结果返回到它的外部查询中。
相关子查询通常使用关系运算符与逻辑运算符(EXISTS、AND、SOME、ANY、ALL)。
EXISTS 代表存在。带有EXISTS量词的子查询不返回任何实际数据,它只产生逻辑真值TRUE或逻辑假值FALSE。若子查询结果非空,则外层的WHERE子句返回真值,否则返回假值。
EXISTS也与NOT结合使用,即NOT EXISTS,其返回值与EXISTS刚好相反。
格式为:[NOT] EXISTS (子查询)
【例】查询1001号课程的成绩小于该课程平均成绩的学生的学号和成绩。
SELECT student_id, grade
FROM score a
WHERE grade<( SELECT AVG(grade)
FROM score b
WHERE a.course_id=b.course_id
AND course_id= '1001'
)
UNION操作符
UNION运算可以将两个或多个查询结果组合成一个结果集。使用UNION运算符组合的结果集都必须具有相同的结构,他们输出的列的数目必须相同,并且相应的结果集列的数据类型必须兼容。
语法格式为:
SELECT 输出列表1 FROM 表名1
UNION [ALL]
SELECT 输出列表2 FROM 表名2
UNION的结果集列名与UNION运算符中第一个SELECT语句结果集中的列名相同。
在默认情况下,UNION运算符将从结果集中删除重复的行。如果使用ALL关键字,那么结果集中将包含所有行而不删除重复行。
如果使用UNION运算符,那么各个SELECT语句不能包含他们自己的ORDER BY或COMPUTE子句,而只能在最后一个SELECT语句的后面使用一个ORDER BY或COMPUTE子句;该子句适用于最终的组合结果集。
【例】分别查询所有学生的1001和1002号课程的成绩,然后联合输出,并按成绩的降序排列。
SELECT student_id, course_id, grade
FROM score
WHERE course_id='1001'
UNION
SELECT student_id, course_id, grade
FROM score
WHERE course_id='1002'
ORDER BY grade DESC
视图的概念:
(1)是虚拟表
(2)来源于对表查询结果 (基表)
(3)也可来源于对视图的查询结果
(4)操作同数据表的操作,对视图的修改实质是修改基表
视图对象的作用有:
●简单性:看到的就是需要的。
●安全性:通过视图用户只能查询和修改他们所能见到的数据。
●逻辑数据独立性:视图可帮助用户屏蔽真实表结构变化带来的影响。
使用对象资源管理器建立视图
使用T-SQL语句建立视图
格式如下:
CREATE VIEW < view_name >[(<字段名>[,…n])]
[WITH ENCRYPTION]
AS
SELECT 语句
[WITH CHECK OPTION]
参数说明:
<字段名>[,…n]:组成视图的字段要么全部省略,要么全部指定。如果省略了视图的各字段名,则隐含该视图由SELECT 子句目标列中的诸字段组成,但在下列三种情况下必须指定组成视图的所有列名:
●某个字段不是单纯的字段名,而是集函数或列表达式
●多表连接时选出了几个同名字段作为视图的字段
●需要在视图中为某个字段启用新的更合适的名字
WITH ENCRYPTION:对视图的定义语句进行加密。可以保障视图的定义不被他人获得。
SELECT语句:定义视图的SELECT语句。该语句可以使用多个表或其他视图。该SELECT语句查询出来的数据就是视图所能观察到的数据。
WITH CHECK OPTION: 表示对视图进行UPDATE、INSERT和DELETE操作时要保证更新、插入和删除的行满足视图中SELECT 语句的条件表达式。如果SELECT语句中任何位置使用了TOP,则不能指定WITH CHECK OPTION。
补充说明:
●CREATE VIEW必须是批处理中的第一条语句。
●只能在当前数据库中创建视图。
●视图最多可以包含1024列。
例 在score数据库中建立一个名为“student_view”的视图,通过视图只能看到学生的学号、姓名、班级和性别。
USE score
GO
CREATE VIEW student_view
AS
SELECT student_id, student_name, sex, class_id
FROM student
查看、修改和删除视图
查看视图信息
使用对象资源管理器查看
使用系统存储过程查看
(1)可以使用系统存储过程sp_help查看视图特征。
格式为: sp_help < view_name >
例 使用sp_help查看视图“student _view”的特征。
USE score
GO
sp_help student_view
(2)可以使用系统存储过程sp_helptext查看视图的定义语句。
格式为: sp_helptext
【例】使用sp_helptext查看视图“student_view”的定义信息。
USE score
GO
sp_helptext student_view
修改视图信息
使用对象资源管理器修改
使用T-SQL语句修改视图
格式为:
ALTER VIEW < view_name>[(<列名>[,…n])]
[WITH ENCRYPTION]
AS
SELECT 语句
[ WITH CHECK OPTION]
参数说明:
ALTER VIEW:指定修改的对象是视图。
View_name:指定要被修改视图的名称。
注意:对视图的具体修改操作与定义视图的方法是一致的。如果原来的视图定义使用了WITH ENCRYPTION或WITH CHECK OPTION,则只有在修改视图的语句中也包含这些选项,它们才会继续有效。
例 修改score数据库中的视图“student_view”,使其只包含男学生的学号、姓名、班级和性别。
USE score
GO
ALTER VIEW student_view
AS
SELECT student_id, student_name, sex, class_id
FROM student
WHERE sex= '男'
删除视图
使用对象资源管理器删除
使用T-SQL语句删除视图
语句格式为:
DROP VIEW < view_name >[,…n]
参数说明:
DROP VIEW:表明要删除的对象是视图。
view_name:指定要删除视图的名称。
例 使用DROP VIEW删除视图“成绩_view”。
USE score
GO
DROP VIEW 成绩_view
通过视图管理表中数据
视图中的数据来源于基本表,通过视图可以观察到基本表中的数据变化,反过来,通过视图可以对基本表中的数据进行操作。操作方式有SELECT、INSERT、UPADTE和DELETE基本表中的数据。
插入记录
通过视图往基本表中插入记录
例 通过视图“student_view”往学生信息表中插入一条记录。
USE score
GO
INSERT student_view(student_id,
student_name,sex,class_id)
VALUES(‘2017010211’,‘张三丰','男',‘20170102')
查询数据
通过视图查询数据
例 通过视图 “student_view” 查询学生的学号、姓名、性别和班级信息。
USE score
GO
SELECT student_id,student_name, class_id
FROM student_view
修改数据
通过视图修改基本表中插入记录
例 通过视图 “student_view” 把学号为”2017010211”的学生的姓名改为张丰。
USE score
GO
UPDATE student_view
SET student_name=‘张丰'
WHERE student_id=‘2017010211'
删除记录
通过视图删除基本表中插入记录
例 通过视图“student_view”把学号为”2017010211”的学生的记录删除。
USE score
GO
DELETE student_view
WHERE student_id=‘2017010211'
注意 :
对视图进行INSERT、UPADTE和DELETE操作时,有以下限制:
●任何修改(包括INSERT、UPADTE和DELETE)都只能针对一个基本表的列。
●视图中被修改的列必须直接引用表列中的原始数据。他们不能通过聚合函数、计算等方式派生。
●受GROUP BY、HAVING或DISTINCT子句的影响的字段不能被修改。
●对列的修改必须满足在基表中对列的约束定义
如:
成绩_view视图(包含学号,姓名,课程名称,成绩)
不能试图对通过该视图完成添加、删除、修改操作
索引包含从表或视图中一个或多个列生成的键,以及映射到指定数据的存储位置的指针
索引的作用:
①通过创建唯一索引,可以保证数据记录的唯一性。
②可以大大加快数据检索速度。
③可以加速表与表之间的连接,这一点在实现数据的参照完整性方面有特别的意义。
④在使用ORDER BY和GROUP BY子句中进行检索数据时,可以显著减少查询中分组和排序的时间。
⑤使用索引可以在检索数据的过程中使用优化隐藏器,提高系统性能。
从索引表的物理顺序、属性列的重复值以及索引列中所包含的列数等不同角度,可以把索引分为聚集索引和非聚集索引、唯一索引和非唯一索引、单列索引和复合索引。
(1)聚集索引
聚集索引是指数据行的物理存储顺序与索引的顺序完全相同,即索引的顺序决定了表中行的存储顺序。
因为记录是经过排序的,所以在每个表上只能创建一个聚集索引。
如果表中没有建立聚集索引,则在对表建立主键约束时会自动创建一个聚集索引。
(2)非聚集索引
非聚集索引具有完全独立于数据行的结构,即索引中的逻辑顺序并不等同于表中行的物理顺序。非聚集索引仅仅记录指向表中行的位置指针,通过指针可以快速在表中定位数据行。
非聚集索引作为与表独立的对象存在,可以为表中每一个常用于查询的列定义非聚集索引。
在一个列上设置唯一性约束时也自动在该列上创建非聚集索引。
(3)唯一索引和非唯一索引
唯一索引确保被索引的列不包含NULL在内的重复值。如果被索引的列是多个列的组合,那么唯一索引也可以确保索引列中的每个组合也是唯一的。因为唯一索引不允许出现唯一值。而非唯一索引没有这个限制。
(4)单列索引和复合索引
单列索引是对表中的单个字段建立的索引。复合索引是对表中的两个或两个以上字段(最多16个字段)的组合建立的索引,并且所有字段在同一个表中。复合索引中的字段顺序可以和表中字段的顺序不同,建议在复合索引中应该首先定义最有可能是唯一值的字段。
(5)视图索引
视图索引将具体化(执行)视图,并将结果集存储在唯一的聚集索引中,而且其存储方法与带聚集索引的表的存储方法相同。创建聚集索引后,可以为视图和唯一性约束的列上会自动创建唯一索引。
(6)全文索引
一种特殊类型的基于标记的功能性索引,由Microsoft SQL Server全文引擎(MSFTESSQL)服务创建和维护,用于帮助在字符串数据中搜索复杂的词。
(7)XML索引
XML数据类型列中XML二进制大型对象(BLOB)的已拆分持久表示形式
(1)创建索引
使用对象资源管理器建立索引
使用T-SQL语句建立索引
格式如下:
CREATE [UNIQUE] [CLUSTERED|NONCLUSTERED ] INDEX index_name ON
{ table | view } ( column [ ASC | DESC ] [ ,...n ] ) }
参数说明:
UNIQUE:用于指定创建唯一索引,即不允许存在索引值相同的两行。
CLUSTERED:用于指定创建的索引为聚集索引。
NONCLUSTERED:用于指定创建的索引为非聚集索引。
index_name:用于指定所创建的索引的名称。
table:用于指定创建索引的表的名称。
view:用于指定创建索引的视图的名称。
column:用于指定被索引的列。
ASC|DESC:用于指定具体某个索引列的升序或降序排序方向。
例 为course表创建了一个唯一非聚集索引,索引名称为C_name_index,被索引的列为 course_name。
CREATE UNIQUE NONCLUSTERED INDEX c_name_index
ON course (course_name)
(2)查看、修改和删除索引
查看索引
索引信息包括索引统计信息和索引碎片信息,通过查看索引信息可以分析索引性能,以便更好的维护索引。
查看索引统计信息
索引统计信息的查询优化器用来分析和评估查询、确定最优查询计划的基础数据。格式如下:
DBCC SHOW_STATISTICS ( table_name, index_name)
参数说明:
table_name:表名。
index_name:索引名。
例 查看student表中的PK_student索引的统计信息。
DBCC SHOW_STATISTICS ('student',pk_student)
统计索引信息包括3个部分:
即统计标题信息、统计密度信息和统计直方图信息。
(1)统计标题信息主要包括表中的行数、统计抽样的行数、所有索引字段的平均长度等。
(2)统计密度信息主要包括索引字段前缀集的选择性、平均长度等信息。
(3)统计直方图信息即为显示直方图时的信息。
查看索引碎片信息
当往表中添加或删除记录以及索引字段的值发生改变时,SQL Server将调整索引页以维护索引数据的存储。页拆分时会产生碎片,查看语法格式如下:
DBCC SHOWCONTIG (table_name, index_name)
例 查看score表中的PK_grade索引的碎片统计信息。
DBCC SHOWcontig (score,pk_grade)
使用系统存储过程查看索引信息
使用系统存储过程可以返回指定表中所有索引的信息。其语法如下:
sp_helpindex [@objname =] 'table_name'
参数说明:
[@objname =] ‘table_name’:指定当前数据库中表的名称。
例 查看学生表中的索引信息。
sp_helpindex student
修改索引
使用系统存储过程修改索引名称,语法如下:
sp_rename ‘table_name.index_name’,
‘new_index_name’ [, ‘object_type’]
参数说明:
①table_name.index_name:指定当前表中需要修改索引名。
②new_index_name:指定新的索引名。
③object_type:被修改对象的类型。
例 把student表中的索引s_name_index修改为s_index。
sp_rename 'student.s_name_index', 's_index', 'index'
删除索引
使用对象资源管理器删除索引
使用T-SQL语句删除索引
格式为:
DROP INDEX 'table.index | view.index' [ ,...n ]
参数说明:
DROP INDEX:表明要删除的对象是索引。
table | view:用于指定被删除的索引所在的表或视图。
index_name:指定要删除索引的名称。
注意:DROP INDEX命令不能删除由CREATE TABLE或者ALTER TABLE命令创建的主键或者唯一性约束索引,即在对表建立主键或唯一性约束时自动建立的聚集索引或唯一非聚集索引;也不能删除系统表中的索引。
例 使用DROP INDEX删除course表中的索引“c_name_index”。
DROP INDEX course.c_name_index
例 修改class表,为class_name列添加唯一性约束,约束名为unique_class_name,这时在class表中自动建立了一个与约束名同名的索引。再使用DROP INDEX删除索引unique_class_name,观察删除结果.
USE score
GO
ALTER TABLE class ADD CONSTRAINT
unique_class_name UNIQUE(class_name)
USE score
GO
DROP INDEX class.unique_class_name
(1)SQL标识符
1)标准标识符
也称为常规标识符。定义标准标识符时应遵守以下规则。
长度:1~128个字符。
第一个字符必须以字母(a~z或A~Z)、下划线(_)、@或#开头
不能是Transact-SQL保留字。
不允许在标识符中嵌入其它特殊字符或空格。
分隔标识符
分隔标识符是包含在双引号("")或中括号([])内的标准标识符或不符合标准标识符规则的标识符。
对于不符合标准标识符规则的,比如对象或对象名称的一部分使用了保留关键字的,或者标识符中包含嵌入空格的,都必须分隔。
2)批处理
批处理是包含一个或多个Transact-SQL语句的的集合,由客户端发送到 SQL Server 实例以完成执行。
GO
注释
SQL Server有以下两种注释字符。
--(双连字符)
/*…*/(斜杠—星号字符对)
常量
常量是指在程序运行过程中值保持不变的量。
字符串常量
用单引号括起来的如:’china’、’SQL Server2014’。
整型常量
由没有用引号括起来且不包含小数点的数字字符串,为整型常量。如:123、2005。
实型常量
由没有用引号括起来且包含小数点的数字字符串,为实型常量。如:123.01、2008.5E4
日期时间型常量
由单引号括起来日期格式的数据,为日期时间型数据。如’2008-10-1’。
货币型常量
以“$”作为前缀的后接数字字符串,为货币型常量。如$125、$5425.12
二进制常量
二进制常量具有前缀0x并且是十六进制数字字符串。这些常量不使用引号括起来。如:0xabc、0x341DF
变量
变量是指在程序运行过程中可以变化的量.
在定义和使用变量时应注意:
遵循“先定义,再使用”的基本原则。
变量名也是一种标识符,所以变量的命名也应遵守标识符的命名规则。
变量的名字尽量做到见名知意,避免变量名与系统保留关键字同名。
变量分为:用户自定义的局部变量和系统提供的全局变量。
局部变量
局部变量是一个能够拥有特定数据类型的对象,它的作用范围仅限制在程序内部.
声明局部变量
语法格式:
DECLARE @variable_name datatype
[,@variable_name datatype ] …
参数说明:
①@variable_name
表示局部变量的名称,必须以“@”符号开头。
②Datatype
为该局部变量指定的数据类型
例 在score数据库中定义一个名称为sum的局部变量,数据为整型。
USE score
GO
DECLARE @sum int
局部变量的赋值
方法一:通过SET语句赋值,格式为:
SET @变量名=表达式
说明:
将表达式的值将赋给左边的变量,SET一次只能对一个变量赋值。变量没有赋值时其值为NULL。
例 声明一个长度为10 个字符的变量“id”并赋值为’200801’,然后输出变量的值。
USE score
GO
DECLARE @id char(10)
Set @id=‘200801’
PRINT @id /*输出变量的值*/
方法二:通过SELECT语句赋值,格式为:
SELECT @变量名=表达式[,…]
[from 表名][WHERE 条件表达式]
参数说明:
①用SELECT赋值时如果省略FROM子句等同于上面的SET方法。若不省略,则将查询到的记录的数据结果赋值给局部变量,如果返回的是记录集,则将记录集中最后一行记录的数据赋值给局部变量。所以尽量限制WHERE条件,使查询结果中只有返回一条记录。
②SELECT可以同时给多个变量赋值。
【例】对上例采用SELECT方式赋值。
USE score
GO
DECLARE @id char(10)
SELECT @id=‘200801’
PRINT @id
【例】定义一个长度为8的字符变量STNameVar,并将student表中学号为2017010101学生的姓名赋值给变量STNameVar,然后输出该变量的值。
DECLARE @STNameVar CHAR(8)
SELECT @STNameVar=student_name
FROM student
WHERE student_id =‘2017010101'
SELECT @STNameVar
全局变量
全局变量是SQL Server系统内部使用的变量,其作用范围并不仅仅局限于某一程序,而是任何程序均可以随时调用。全局变量通常存储一些SQL Server的配置设定值和统计数据。用户可以在程序中用全局变量来测试系统的设定值或者是Transact-SQL命令执行后的状态值。且全局变量的名字均以@@开头。
用户不能建立全局变量,也不能用SET或SELECT语句对全局变量赋值。
例如:@@rowcount记录前一条SQL语句处理记录的行数;@@version记录SQL Server的版本信息;@@servername记录当前服务器的名称。
在SQL Server中,运算符主要有以下六大类:算术运算符、赋值运算符、位运算符、比较运算符、逻辑运算符以及字符串串联运算符等。
算术运算符
算术运算符包括加(+)、减(—)、乘(*)、除(/)和取模(%,返回两个数相除后的余数)。
赋值运算符
Transact-SQL 中只有一个赋值运算符(=)
位运算符表
【例】输出对1与0按位求与运算、或运算和异或运算的结果。
DECLARE @a bit, @b bit, @c bit
SET @a=1&0
SET @b=1|0
SET @c=1^0
PRINT @a PRINT @b PRINT @c
字符串联运算符
字符串联运算符只有一个,即加号“+”。利用字符串运算符可以将多个字符串连接起来,构成一个新的字符串。
例如,执行语句SELECT ‘abc’+’def’,其结果为abcdef。
【例】查询student表中学生的姓名和学号,要求两者要作为一列结果输出,学号和姓名间用字符“–”隔开。
USE SCORE
GO
SELECT student_id +'--'+student_name
FROM student
SQL Server中的流程控制语句主要包括程序块语句、选择结构语句、强制转移语句、循环控制语句、等待语句和显示信息语句等。
程序块语句——BEGIN…END
其语法形式为:
BEGIN
SQL语句1
SQL语句2
…
END
选择结构语句——IF…ELSE
不含ELSE子句
IF 布尔表达式
SQL语句块
若IF后面的布尔表达式为真,则执行SQL语句块,然后执行IF结构后面的语句;否则跳过语句块直接执行IF结构后面的语句。
包含ELSE子句
IF 布尔表达式
SQL 语句块1
ELSE
SQL语句块2
若IF后面的布尔表达式为真,则执行SQL语句块1,否则执行SQL语句块2。然后执行IF…ELSE结构后面的语句。
【例】判断学号为2017010101的学生1001号课程的成绩是否大于60分,如果大于60,输出’grade above 60’;否则输出’grade below or equal 60’。
USE SCORE
GO
IF (SELECT grade
FROM score
WHERE student_id=‘2017010101'
and course_id='1001')>60
print 'grade above 60'
ELSE
print 'grade below or equal 60'
循环控制语句—WHILE、CONTINUE和BREAK
WHILE循环的语法格式如下:
WHILE <条件表达式>
BEGIN
< SQL语句块>
END
【例】求1到100的和。
Declare @num int, @sum int
Select @num=1, @sum=0
While @num<=100
Begin
set @sum=@sum+@num
set @num=@num+1
End
Print @sum
WHILE语句还常与CONTINUE和BREAK一起使用。
(1)CONTINUE语句可以使程序跳过CONTINUE语句后面的语句,开始下一次循环条件判断;
(2)BREAK语句则使程序终止循环,结束WHILE语句的执行。WHILE 语句也可以嵌套。
引入CONTINUE与BREAK命令的WHILE循环的语法格式如下:
WHILE <条件表达式>
BEGIN
< SQL 语句块>
[ BREAK ]
[ CONTINUE ]
[ SQL 语句块]
END
[例】求1到100之间的偶数和(包括100)。
Declare @num int, @double_sum int
Select @num=0, @double_sum=0
While @num<=100
Begin
set @num=@num+1
if @num%2!=0
continue
else
set @double_sum=@double_sum+@num
End
print '偶数和为:'
print @double_sum
强制转移语句——GOTO
GOTO语句的语法格式有以下两种形式。
形式一:标签在GOTO语句后面定义。
GOTO label
……
label:
形式二:标签在GOTO语句前面定义。
Label:
……
GOTO label
注:Label为标签名称
【例】求1到100的和。
Declare @num int, @sum int
Select @num=1, @sum=0
label: if(@num<=100)
begin
set @sum=@sum+@num
set @num=@num+1
goto label
end
print @sum
无条件退出语句——RETURN
RETURN语句用于无条件地终止一个查询、存储过程或者批处理,不执行位于RETURN语句之后的程序。
语法格式为:
RETURN [整形表达式]
参数说明:
“整形表达式”为返回的整型值。存储过程可以给调用过程或应用程序返回一个整型值。在系统存储过程中返回零值表示成功,返回非零值则表示有错误发生。
等待语句——WAITFOR
语法形式为:
WAITFOR { DELAY ‘time’ | TIME ‘time’ }
参数说明:
①DELAY:用于指定程序等待的时间间隔,最长可达24小时。
②TIME:用于指定某一时刻。当时间达到这个一个时刻时开始执行程序。
③’time’的数据类型为datetime,格式为‘hh:mm:ss’。
【例】等待1分零3 秒后才执行SELECT 语句
WAITFOR delay ’00:01:03’
select * from student
【例】直到中午11 点零8 分后才执行SELECT 语句。
waitfor time ’11:08:00’
select * from student
显示信息语句——PRINT
语法格式如下:
PRINT <字符串>|<变量名>|<表示式>
SQL Server函数分为内部函数和用户自定义函数
1)内部函数
作用:是用来帮助用户获得系统的相关信息、执行相关计算、实现数据转换以及统计等诸多功能。
字符串函数
字符串函数可以对二进制数据、字符串进行处理
(1)统计字符串长度函数
LEN(string_expression)
(2)字符串截取函数
LEFT(string_expression,n)
RIG HT(string_expression,n)
SUBSTRING(string_expression,start,n)
(3)字符串转换函数
LTRIM(string_expression)
RTRIM(string_expression)
CHAR(integer_expression)
例】使用LEN函数统计字符串:’SQL Server2014’的长度。
PRINT LEN('SQL Server2014')
数学函数
ROUND(numeric_expression,n)
ABS(numeric_expression)
SQRT(numeric_expression)
【例】对数值0.25进行以下操作:
(1)舍入操作,小数位保留1位有效数字。
PRINT ROUND(0.25,1)
(2)输出数值的绝对值。
PRINT ABS(0.25)
(3)输出数值的平方根。
PRINT SQRT(0.25)
日期和时间函数
GETDATE( ) YEAR(date)
MONTH(date) DAY(date)
DATEADD(datepart,n,date)
DATEDIFF(datepart , date1 , date2 )
【例】输出当前日期的年份、月份和几号;计算在2018年10月1日的基础上增加50天的日期;计算2020年国庆距离现在还有多少天。
PRINT YEAR(GETDATE())
PRINT MONTH(GETDATE())
PRINT DAY(GETDATE())
PRINT DATEADD(day, 50, ‘2018-10-1’)
PRINT DATEDIFF(DAY, GETDATE(), ‘2020-10-1’)
系统函数
CASE函数
CASE函数可以计算多个条件式,并将其中一个符合条件的结果表达式返回,常用于多分支结构的流程控制中。
按照使用形式的不同,分为简单CASE函数和搜索CASE函数。
简单CASE函数的语法形式:
CASE input_expression
WHEN when_expression THEN result_expression
[ ...n ]
[ ELSE else_result_expression]
END
【例】在student表中查询20170101班、20170102班、20170103班学生,然后根据班级编号与班级名称的对应关系,输出学号和班级名称,如果不是这个三个班的学生,班级名称输出为NULL。
SELECT student_id,
CASE class_id
when ‘20170101’ THEN ’17计算机1班'
when ‘20170102’ THEN ’17计算机2班'
when ‘20170103’ THEN ‘17计算机3班'
ELSE 'NULL'
END '班级名称'
FROM student
搜索 CASE函数的语法形式:
CASE
WHEN Boolean_expression THEN result_expression [ ...n ]
[ ELSE else_result_expression
END
【例】编写程序查询学号为2017010101的学生各门课程的成绩,并将成绩转换为不同的等级。
SELECT course_id,
CASE
when grade>89 THEN '优秀'
when grade>79 and grade<=89 THEN '良好'
when grade>69 and grade<=79 THEN '中等'
when grade>59 and grade<=69 THEN '及格'
ELSE '不及格'
END '等级'
FROM score Where student_id=’2017010101’
类型转换函数
CAST (expression AS data_type)
将表达式(expression)转换为指定的数据类型(data_type)
【例】查询学生的学号、课程编号和成绩,在输出结果中把成绩转化为精确数值型decimal(4,1)。
SELECT student_id, course_id,
CAST(grade as decimal(4,1))’成绩’
FROM score
2)用户自定义函数
SQL Server 中根据函数返回值形式的不同将用户自定义函数分为三种类型: 标量型函数、内嵌表值型函数和多语句表值函数。
标量函数
标量函数返回一个具有确定数据类型的标量值,其返回值数据类型为除TEXT、NTEXT和TABLE等类型外的其它数据类型。函数体语句定义在BEGIN-END语句内。
标量函数的定义
语法格式如下:
CREATE FUNCTION [owner_name.]函数名称
([@形式参数名称 [AS] 数据类型[=default] [,……] ])
RETURNS 返回数据类型
[as]
BEGIN
函数体
RETURN 表达式
END
【例】编写一个标量函数:以学号和课程编号做为参数,输入学号和课程编号后得到该学生该门课程的成绩。
CREATE FUNCTION F_grade(@s_id char(10), @c_id char(5))
RETURNS INT
AS
BEGIN
DECLARE @G INT
SET @G=(SELECT grade
FROM score
WHERE student.student_id=@s_id
and course_id=@c_id)
RETURN @G
END
标量函数的调用
可以在使用标量表达式的位置调用标量函数,也可以使用EXECUTE语句执行标量函数。执行标量函数有两种方法,
1)owner_name.函数名(实参1,……,实参n)
2)EXEC owner_name.函数名 实参1,……,实参n
或:EXEC owner_name.函数名 形参1=实参1,…,形参n=实参n
【例】分别用两种方法调用F_grade函数,完成查看2017010101号学生1001号课程的成绩。
方法一:
USE SCORE
GO
PRINT dbo.F_grade(‘2017010101','1001')
方法二:
USE SCORE
GO
DECLARE @成绩 int
EXEC @成绩=dbo.F_grade ‘2017010101','1001'
PRINT @成绩
练习:编写一个函数:输入学号后得到该学号对应的姓名。学号作为函数的输入参数。
Create function fn_stuName(@stuId as char(10))
Returns char(10)
Begin
declare @Name char(10)
set @Name=
( select 姓名
from 学生基本信息表
where 学号=@stuId
)
return @Name
end
内嵌表值型函数
内嵌表值型函数返回值的类型为table,即它返回的是一个表,返回的表中的数据由位于RETURN 子句后的SELECT语句决定。
内嵌表值型函数的定义
语法格式如下:
CREATE FUNCTION [ower_name.]函数名称
([@形式参数名称 [AS] 数据类型[=default] [,……] ])
RETURNS table
RETURN [(select-stmt)]
【例】建立一个函数,以学号和课程编号做为参数,输入学号和课程编号后得到该学生学号、姓名、课程编号和成绩。
USE SCORE
GO
CREATE FUNCTION F_s_grade(@s_id char(10),@c_id char(5))
RETURNS TABLE
RETURN
SELECT student.student_id, student_name,
course_id, grade
FROM student, score
WHERE student.student_id=score.student_id
and student.student_id=@s_id
and course_id=@c_id
内嵌表值型函数的调用
内嵌表值型函数只能通过select语句调用。调用语法格式为:
SELECT * FROM 函数名(实参1,……,实参n)
【例】调用函数F_s_grade,查看2017010101号学生1001号课程的成绩。
SELECT * FROM F_s_grade(‘2017010101','1001')
多语句表值函数
多语句表值函数可生成记录,并将记录插入返回的表类型的变量中。
(1)多语句表值函数的定义
CREATE FUNCTION [owner_name.]函数名称
([@形式参数名称 [AS] 数据类型[=default] [,……] ])
RETURNS @return_variable TABLE <table_type_definition>
BEGIN
函数体
RETURN
END
【例】建立一个函数,查询学生的学号、姓名、课程编号和成绩,并将这些信息插入到一个表类型变量中。
USE SCORE
GO
CREATE FUNCTION F_student_grade()
RETURNS @result TABLE (s_id char(10),
name char(8),
c_id char(5),
result int )
BEGIN
INSERT @result
SELECT student.student_id, student_name, course_id, grade
FROM student, score
WHERE student.student_id=score.student_id
RETURN
END
多语句表值函数的调用
多语句表值函数的调用与内嵌表值型函数的调用方法相同。调用语法格式为:
SELECT * FROM 函数名([实参1,……,实参n])
【例】调用F_student_grade函数
SELECT * FROM F_student_grade()
删除用户自定义函数
使用 DROP FUNCTION语句可以删除当前数据库中指定的一个或多个函数。其语法如下:
DROP FUNCTION { [ owner_name. ] 函数名称 } [ ,...n ]
【例】删除数据库score中的用户自定义函数F_student_grade
DROP FUNCTION F_student_grade
练习:
1、创建一个标量函数,输入学号得到该学生的平均成绩。
create function avg2(@xh char(8))
returns decimal(5,2)
begin
declare @a decimal(5,2)
set @a=(select avg(成绩) from 成绩表
where 学号=@xh)
return @a
End
2、创建一个多语句函数,以课程编号为参数,函数的功能是查找选修 了该门课的学生姓名和成绩。
create function c_grade(@c_n char(8))
returns @cno table
(s_no char(8),c_no char(5),cj decimal(5,2))
begin
insert @cno
select 学号,课程编号,成绩
from 成绩表
where 课程编号=@c_n
return
End
执行:
select * from c_grade(‘1001')
存储过程概述
存储过程(Stored Procedure)是一组为了完成特定功能的SQL 语句集,经编译后存储在数据库中。
一般用来处理需要与数据库进行频繁交互的复杂的业务。因为存储过程具有以下优点:
①存储过程在服务器端运行,执行速度快。
②封装业务逻辑也可以使数据库操作人员与应用系统开发人员的分工更明确,支持模块化设计。
③存储过程执行一次后,其执行计划就驻留在高速缓冲存储器,如果需要再次调用,只需要从高速缓冲存储器中调用,提高系统性能。
④存储过程可以作为安全机制。通过授予用户对存储过程的操作权限来实现安全机制。
⑤使体现企业规则的运算程序放入数据库服务器中,以便集中控制。
存储过程的分类
1.系统存储过程
系统存储过程存储在master数据库中,以sp_开头,可以在其他数据库中进行调用。
如:sp_help就是取得指定对象的相关信息。
2.扩展存储过程
在SQL Server环境之外执行动态链接库称为扩展存储过程,以XP_开头,用来调用操作系统提供的功能。
3.用户自定义的存储过程
由用户创建并能完成某一特定功能的存储过程。包括Transact-SQL和CLR两种类型。
(1)Transact-SQL存储过程是指保存的Transact-SQL语句集合,可以接受和返回用户提供参数。也可以从数据库向客户端应用程序返回数据。
(2)CLR在本书不做详细介绍。
建立存储过程
使用对象资源管理器建立存储过程
使用T-SQL命令建立存储过程
语法形式如下:
CREATE PROC[EDURE] procedure_name
[{@parameter data_type}
[VARYING] [=default][OUTPUT] ] [,...n]
[WITH {RECOMPILE|ENCRYPTION|RECOMPILE,
ENCRYPTION}]
[FOR REPLICATION]
AS
sql_statement [ ...n ]
【例】创建一个不带参数的存储过程,名称为pro_stu,用于检索学生的姓名、性别和家庭住址。
USE score
GO
--判断pro_stu存储过程是否存在,若存在,则删除
If exists(select name from sysobjects
where name='pro_stu' and type='p')
DROP PROCEDURE pro_stu
Go
--建立存储过程
CREATE PROC pro_stu
As
SELECT student_name, sex, address
FROM student
【例】创建一个带参数的存储过程,名称为pro_class,在执行存储过程的时候输入班级编号,然后检索该班级的学生的详细信息。
USE score
GO
--判断pro_class存储过程是否存在,若存在,则删除
If exists(select name from sysobjects
where name='pro_class' and type='p')
DROP PROCEDURE pro_class
Go
--建立存储过程
CREATE PROC pro_class @c_no char(8)
As
SELECT *
FROM student
WHERE class_id=@c_no
存储过程的执行
语法形式如下:
[[EXEC[UTE]]
{
[@return_status =]
{procedure_name|@procedure_name_var}
[[@parameter=]{value|@variable[OUTPUT]|[DEFAULT]
}
[,...n]
[ WITH RECOMPILE ]
1.无参存储过程的执行
【例题9.3】执行在例题10.1中创建的存储过程pro_stu。
EXEC pro_stu
2.带参存储过程的执行
在执行带参存储过程的时候参数有以下几种传递方式:
(1)顺序法
【例】建立一个存储过程pro_update,通过指定学号和课程编号来把成绩表中的成绩修改为指定的某个值,然后执行该存储过程。
CREATE PROC pro_update
@s_id char(10), @c_id char(5), @result int --参数
AS
UPDATE score
SET grade=@result
WHERE student_id=@s_id AND course_id=@c_id
/
*顺序法执行存储过程,把0801101号学生1001号课程的成绩修改为85分*/
EXEC pro_update '0801101', '1001', 85
(2)提示法
【例】通过提示法来执行存储过程pro_update。
EXEC pro_update @s_id=’0801101’,
@result=85,@c_id=’1001’
说明:提示法中的参数顺序可以与建立存储过程时的参数顺序不一致,而顺序法必须保持一致。
(3)使用默认参数
建立存储过程时,可以指定参数的默认值,默认值必须为常量或者为NULL。
【例】建立一个存储过程pro_insert,用来完成向课程表中插入记录的功能,然后执行该存储过程并检查执行结果。
CREATE PROC pro_insert @c_id char(5), @c_name char(20),
@period int=64, @c_type char(10)='NULL'
AS
INSERT course
VALUES( @c_id ,@c_name,@period,@c_type )
GO
--执行存储过程pro_insert
EXEC pro_insert '1006', 'c++程序设计'
GO
--查看插入结果
SELECT * FROM course
(4)使用带OUTPUT的返回参数
在建立存储过程时,通过定义输出参数,可以从存储过程中返回一个或多个值。在执行存储过程时,可以将结果返回给返回参数。定义输出参数需要在参数定义的数据类型后使用关键字OUTPUT,或省写为OUT。
【例】建立一个带参数的存储过程,用于求两个整数的和,其中和定义为OUTPUT参数,然后执行存储过程并输出和。
CREATE PROC pro_sum
@a int ,@b int, @sum int output
AS
SET @sum=@a+@b
GO
--执行存储过程
DECLARE @s int
EXEC pro_sum 20 ,15,@s output
PRINT @s
存储过程的返回值
存储过程被执行以后可以返回一个整数类型的代码值,该值用来记录存储过程的执行情况。若返回值为0,表示执行成功;否则表示执行不成功。
捕捉存储过程返回值的方法
1)用一个变量来捕捉存储过程执行后返回值。
2)使用RETURN语句为存储过程指定一个确定的返回值,以用来反映存储过程执行的结果情况。
【例】用变量来捕捉存储过程执行后返回值。建立一个存储过程,完成查询指定学生指定科目的成绩。然后执行该存储过程并捕捉执行是否成功。
CREATE PROC pro_grade @s_id char(10), @c_id char(5)
AS
SELECT grade
FROM score
WHERE student_id=@s_id AND course_id=@c_id
GO
DECLARE @status int --声明变量,用来存放执行结果的状态
EXEC @status=pro_grade '0801101','1001'
SELECT @status --输出状态值
【例】使用RETURN语句为存储过程指定一个确定的返回值。建立一个存储过程,完成查询指定学生指定科目的成绩,如果成绩大于60分,返回1;如果等于60分,返回0;小于60分,则返回-1。然后执行该存储过程并输出返回值。
CREATE PROC pro_return @s_id char(10), @c_id char(5)
AS
DECLARE @result int
SELECT @result=grade
FROM score
WHERE student_id=@s_id AND course_id=@c_id
IF @result>60 RETURN 1
IF @result=60 RETURN 0
IF @result<60 RETURN -1
GO
DECLARE @status int --声明变量,用来存放执行结果的状态
EXEC @status=pro_return '0801101','1001'
SELECT '状态'=@status --输出状态值
查看、修改和删除存储过程
1.修改存储过程
语法形式如下:
ALTER PROC[EDURE] procedure_name
[{@parameter data_type}
[VARYING] [=default][OUTPUT] ] [,...n]
[WITH {RECOMPILE|ENCRYPTION|RECOMPILE,ENCRYPTION}]
[FOR REPLICATION]
AS
sql_statement [ ...n ]
【例】修改存储过程pro_sum,使其功能更改为输出两个数相加的和,不使用返回参数。
USE score
GO
ALTER PROC pro_sum @a int ,@b int
AS
DECLARE @sum int
SET @sum=@a+@b
PRINT @sum
2.查看存储过程
(1)使用对象资源管理器查看
(2)使用T-SQL命令查看
1)查看存储过程的参数及其数据类型
格式:sp_help name
2)查看存储过程的源代码
格式:sp_helptext name
3)查看和存储过程相关的数据库对象
格式:sp_depends name
【例】查看存储过程pro_return的定义文本。
EXEC sp_helptext pro_return
【例】查看存储过程pro_return的所有者、类型及参数。
EXEC sp_help pro_return
【例】查看存储过程pro_return的相关性。
EXEC sp_depends pro_return
3.删除存储过程
(1)使用对象资源管理器删除存储过程
(2)使用T-SQL语句删除存储过程
语法格式:
DROP PROC[EDURE] {procedure_name} [,…n]
【例】删除存储过程pro_return。
DROP PROC pro_return
触发器的概述
Microsoft SQL Server 提供了两种主要机制来强制执行业务规则和数据完整性:约束和触发器。
触发器的主要作用就是其能够实现由主键和外键所不能保证的复杂的参照完整性和数据的一致性。具体表现为:
①触发器可以通过数据库中的相关表进行级联更改。
②触发器可以防止恶意或错误的UPDATE、 INSERT、 DELETE 、CREATE和ALTER操作,这些限制比用 CHECK 约束所定义的更复杂。
③触发器可以评估数据修改前后表的状态,并根据该差异采取措施。
④一个表可以有多个同类触发器允许采取多个不同的操作来响应同一个修改语句。
触发器的类型
两大类触发器:DML触发器和DDL触发器。
1.DML触发器(数据操纵insert,update,delete)
DML触发器是当数据库服务器中发生数据操作语言事件时所执行的操作 .
DML触发器有三种类型:AFTER触发器、INSTEAD OF触发器和CLR触发器。
(1)AFTER触发器
表示只有在执行了指定的操作(INSERT、 DELETE、 UPDATE)之后触发器才被激活,执行触发器中的SQL 语句。若只指定FOR, 则默认为AFTER 触发器,且该类型触发器仅能在表上创建。
(2)INSTEAD OF触发器
指定用触发器中的操作代替触发语句的操作,也就是该触发器并不执行所定义的操作(INSERT、 DELETE、 UPDATE),而是执行触发器本身的SQL语句。可以为基于一个或多个表的视图定义INSTEAD OF触发器,而这些触发器可能够扩展视图可支持的数据类型。
2.DDL触发器(数据定义类)
DDL触发器是一种特殊的触发器,当服务器或数据库中发生数据定义语言(DDL,CREATE、DROP、ALTER等)事件时将激活这些触发器。他们可以用于在数据库中执行管理任务,譬如,审核以及规范数据库操作。DDL触发器无法作为INSTEAD OF触发器使用。
如果要执行以下操作,可以考虑使用DDL触发器。
①防止他人对数据库架构进行修改。
②希望数据库发生某种情况以响应数据库架构中的更改。
③要记录数据库架构中的更改或事件。
建立DML触发器
(1) 使用对象资源管理器建立DML触发器
(2) 使用T-SQL语句建立DML触发器
语法格式:
CREATE TRIGGER trigger_name ON {table|view}
[WITH ENCRYPTION]
{
{{FOR | AFTER | INSTEAD OF }
{[ DELETE ] [,] [ INSERT ] [,] [ UPDATE ]}
AS
sql_statement[...n]
}
}
【例】在student表中创建了一个触发器,当往该表中成功插入记录时,输出提示信息。然后执行插入记录操作,检验触发器。
--判断insert_stu触发器是否存在,若存在,则删除
IF EXISTS (SELECT name FROM sysobjects
WHERE name = 'insert_stu' AND type = 'TR')
DROP TRIGGER insert_stu
GO
--建立触发器
CREATE TRIGGER insert_stu ON student
FOR INSERT
AS
PRINT '插入记录成功'
--插入记录,激活触发器
INSERT student(student_id,student_name,sex,class_id)
VALUES(‘2017010112','吴盼盼','男',‘20170101')
DML触发器的应用
(1)inserted表和deleted表
在执行触发器时,SQL Server 会为触发器建立两个临时表:deleted 表和 inserted,它们的结构和触发器所在的表的结构相同
Inserted表存储INSERT和UPDATE语句所影响的行的副本。在一个插入或更新事务处理中,新建行被同时添加到inserted表和触发器表中。Inserted表中的行是触发器表中新行的副本。
Deleted表存储DELETE和UPDATE语句所影响的行的副本。在执行DELETE或UPDATE语句时,记录从触发器表中删除,并传输到deleted表中。Deleted表和触发器表通常没有相同的行。
注意一:执行 UPDATE 语句时,会被视为插入或删除事务,旧的行值会保留一份副本在deleted表中,而新的行值的副本则保留在触发器表与inserted表。
注意二:inserted和deleted表中的值只限于在触发器中使用。一旦触发器完成就无法再使用。
【例】建立一个触发器,在修改数据时激活该触发器。然后执行修改操作,查看inserted和deleted表中的数据。
--建立触发器
CREATE TRIGGER update_stu
ON student
FOR insert, update,delete
AS
SELECT * FROM inserted
SELECT * FROM deleted
--修改数据,激活触发器
UPDATE student
SET sex='男' WHERE student_id=2017010101'
(2)INSERT触发器
当往表中插入记录时,INSERT触发器被执行。一般情况下,INSERT触发器被用来更新时间标记字段,或者验证被触发器监控的字段中的数据是否满足要求,以确保数据完整性。
【例】建立一个触发器,当向成绩表中插入一条记录时,检查被插入的成绩是否大于等于0和小于等于100。若不满足该条件,不允许插入记录。
CREATE TRIGGER check_insert ON score
AFTER insert
AS
DECLARE @成绩 int
SELECT @成绩=grade
FROM inserted
IF @成绩>=0 AND @成绩<=100
PRINT '插入成功'
ELSE
BEGIN
PRINT '成绩值超出范围,不允许插入'
ROLLBACK TRANSACTION
END
--插入记录,检验insert触发器的作用
INSERT grade(student_id,course_id,grade)
VALUES(‘2017010101','1001',-10)
(3)UPDATE触发器
修改触发器和插入触发器的工作过程基本上一致,修改一条记录等于插入了一条新的记录并且删除一条旧的记录。
【例】假设成绩信息被成功录入到表中以后将允许修改,建立一个触发器,禁止其修改成绩。
CREATE TRIGGER check_update ON score
AFTER update
AS
IF update(grade)
BEGIN
PRINT '修改无效,成绩被录入后,不允许修改'
ROLLBACK TRANSACTION
END
--修改成绩值,检查 update触发器的作用
UPDATE score
set grade=80
WHERE student_id= 2017010104 '
AND course_id='1001'
(4)DELETE触发器
DELETE触发器通常用于两种情况,第一种情况是为了防止那些确实需要删除但会引起数据一致性问题的记录的删除。
第二种情况是执行可删除主记录的子记录的级联删除操作。可以使用这样的触发器从主销售记录中删除所有的定单项。
【例】在学生表中建立一个触发器,若删除学生记录,则把该学生在成绩表中的成绩记录一并删除。
CREATE TRIGGER check_delete ON student
AFTER delete
AS
DELETE score
WHERE student_id in
(SELECT student_id
FROM deleted)
--删除学生记录,检查 delete触发器的作用
DELETE student
WHERE student_id=' 2017010102 '
--查看成绩表 grade中‘2017010102’号学生的成绩是否被删除
SELECT *
FROM grade
DDL触发器
1、建立DDL触发器
CREATE TRIGGER trigger_name ON {ALL SERVER|DATABASE}
[WITH ENCRYPTION]
{FOR | AFTER}
{event_type|event_group}[,…n]
AS
{sql_statement[…n] }
参数说明:
②ALL SERVER
指明触发器的作用域为当前服务器。如果指定了此参数,则只要当前服务器中的任何位置出现event_type或event_group,就会激活触发器。
③DATABASE
指明触发器的作用域为当前数据库。如果指定了此参数,则只要当前数据库中的任何位置出现event_type或event_group,就会激活触发器。
⑤event_type
将导致激活DDL触发器的T-SQL语言的名称。event_type选项有:CREATE_TABLE、CREATE_ DATABASE 、ALTER_TABLE等等。
⑥event_group
预定义的T-SQL语言事件分组的名称。执行任何属于event_group的T-SQL语言事件,都将激活DDL触发器。
event_group有:DDL_SERVER_SECURITY_EVENTS代表所有以服务器为目标的各类DDL语法语法事件,而 DDL_TABLE_VIEW_EVENTS代表了针对数据表、视图表、索引与统计的DDL事件。
【例】使用 DDL 触发器来防止数据库score中的表被任意修改或删除。
USE score
GO
CREATE TRIGGER safety
ON DATABASE
FOR DROP_TABLE, ALTER_TABLE
AS
BEGIN
PRINT '禁止修改或删除表'
ROLLBACK
END
--修改表,检验safety触发器的功能
ALTER TABLE student
ADD f_name char(8)
【例】建立 DDL 触发器来防止在当前服务器下建立数据库。
CREATE TRIGGER forbid_create
ON ALL SERVER
FOR CREATE_DATABASE
AS
BEGIN
PRINT '禁止建立数据库'
ROLLBACK
END
--建立数据库,检验forbid_create触发器的功能
CREATE DATABASE book
查看、修改和删除触发器
查看触发器
(1)使用对象资源管理器查看触发器信息
(2)使用系统存储过程查看触发器
(1)sp_help:用于查看触发器的一般信息,如触发器的名称、属性、类型和创建时间。
格式:sp_help ‘触发器名称‘
(2) sp_helptext:用于查看触发器的正文信息
格式:sp_helptext ‘触发器名称’
(3) sp_depends:用于查看指定触发器所引用的表或者指定的表涉及到的所有触发器。
sp_depends ’触发器名称’
sp_depends ‘表名’
【例】查看check_delete触发器的定义信息。
sp_helptext check_delete
修改触发器
(1)修改DML触发器
ALTER TRIGGER trigger_name ON {table|view}
[WITH ENCRYPTION]
{
{{FOR | AFTER | INSTEAD OF }
{[ DELETE ] [,] [ INSERT ] [,] [ UPDATE ]}
[NOT FOR REPLICATION]
AS
sql_statement[...n]
}
}
(2)修改DDL触发器
ALTER TRIGGER trigger_name ON {ALL SERVER|DATABASE}
[WITH ENCRYPTION]
{FOR | AFTER}
{event_type|event_group}[,…n]
AS
{sql_statement[...n] }
删除触发器
(1)删除DML触发器
DROP TRIGGER { trigger } [ ,…n ]
【例】删除例题中建立在成绩表上的check_update触发器。
USE scoure
GO
DROP TRIGGER check_update
(2)删除DDL触发器
DROP TRIGGER { trigger } [ ,…n ]
ON {ALL SERVER|DATABASE} [;]
【例】删除例题中建立在score数据库中的safety触发器。
USE score
GO
DROP TRIGGER safety ON DATABASE
(3)删除触发器所在的表时,SQL Server将会自动删除与该表相关的触发器。
思考:触发器、存储过程和函数三者有何区别?
触发器是特殊的存储过程,存储过程需要程序调用,而触发器会自动执行;函数是根据输入产生输出,自定义函数的输入输出的关系由用户来定义。在什么时候用触发器?要求系统根据某些操作自动完成相关任务,比如,根据买掉的产品的输入数量自动扣除该产品的库存量。什么时候用存储过程?存储过程就是程序,它是经过语法检查和编译的SQL语句,所以运行特别快。
备份概述
数据库备份就是创建完整数据库的副本,以便当数据遭到灾难性的破坏时可以用副本恢复数据。数据备份和还原永远都是保护数据的重要手段之一。
执行备份操作对运行中的事务影响很小,因此可以在正常操作过程中执行备份操作。但如果进行备份操作时尝试建立或删除数据库文件,则创建或删除将会失败;如果在创建或删除数据库文件时尝试进行备份,则备份操作将等待,直到创建或删除数据库文件完成。
备份的类型
(1)数据库完整备份:是指对数据库内所有内容都进行备份,所以占用的空间和时间较多。
(2)差异备份:只备份最后一次数据库完整备份以来被修改的数据,占用的时间和空间较少。
(3)事务日志备份:只备份数据库的事务处理记录。备份所用的时间和空间更少。利用事务日志备份进行恢复时,可以指定恢复到某一个事务。
(4)文件和文件组备份:即备份数据库文件或文件组。这种备份应该与事务日志备份结合起来才有意义。
如某数据库中有两个数据文件,一次仅备份一个文件,而且在每个数据文件备份后,都要进行日志备份。在恢复数据时,可使用事务日志使所有的数据文件恢复到同一个时间点。
创建备份设备
SQL Server备份是创建在备份设备上的,所以在对数据库进行备份之前,需要先创建一个备份设备,如磁盘、或磁带煤体。
使用对象资源管理器创建备份设备
使用系统存储过程创建备份设备
语法格式如下:
Sp_addumpdevice [@devtype]’device_type’
,[@logicalname]=’logical_name’
,[@physicalname]=’physical_name’
参数说明:
①[@devtype]’device_type’:指定备份设备的类型,可以是disk或tape等,分别表示磁盘和磁带设备。
②[@logicalname]=’logical_name’:指定备份设备的逻辑名称。
③[@physicalname]=’physical_name’:指定备份设备的物理名称。必须包含完整的路径
【例】在本地磁盘上创建一个备份设备,其逻辑名称为bk_score,物理名称bk_score.bak,路径为“E:\ backupfile\”。
exec sp_addumpdevice 'disk','bk_score','
e:\backupfile\bk_score.bak'
使用对象资源管理器备份数据库
使用T-SQL语句备份数据库
BACKUP命令用来对指定数据库进行完整备份、文件和文件组和事务日志备份。
1.完整备份数据库的语法格式如下:
BACKUP DATABASE database_name TO <backup_device>[,…n]
参数说明:
database_name:需要备份的数据库的名称
② backup_device:是指事先建立好的备份设备的逻辑名称。
【例】先建立一个名为score_bak的备份设备,然后使用BACKUP DATABASE创建score数据库的完整备份,将数据库备份到备份设备score_bak上。
USE master
GO
EXEC sp_addumpdevice 'disk','score_bak','d:\score_bak'
GO
BACKUP DATABASE score TO score_bak
2.文件和文件组备份的语法格式如下:
BACKUP DATABASE database_name
{ FILE=logical_file_name | FILEGROUP = logical_filegroup_name } [ ,...f ]
TO backup_device [ ,...n ]
参数说明:
① file:指定包含在数据库备份中的文件的逻辑名,可以同时指定多个文件,文件名之间用逗号隔开。
②filegroup:指定包含在数据库备份中的文件组的逻辑名,可以指定多个文件组,文件组名之间用逗号隔开。
③[ ,…f ]:表示可以指定多个文件和文件组的占位符。不限制文件或文件组的数量。
④backup_device:备份设备名。
【例】先建立一个名为file_bak的备份设备,然后使用BACKUP DATABASE对score数据库中的逻辑名为“score”的文件进行备份,将文件备份到备份设备file_bak上。
USE master
GO
EXEC sp_addumpdevice 'disk','file_bak','d:\file_bak'
GO
BACKUP DATABASE score file='score' TO file_bak
3.日志文件备份的语法格式如下:
BACKUP LOG database_name TO backup_device [ ,...n ]
【例】先建立一个名为log_bak的备份设备,然后使用BACKUP LOG对score数据库中的逻辑名为“score_LOG”的日志文件进行备份,将文件备份到备份设备log_bak上。
USE master
GO
EXEC sp_addumpdevice 'disk','log_bak','d:\log_bak'
GO
BACKUP LOG score TO log_bak
恢复数据库,就是当数据库中的数据遭受破坏时,即可根据备份文件让数据库恢复到备份时的状态。
使用对象资源管理器恢复数据库
使用T-SQL语句恢复数据库
使用T-SQL语句恢复数据库的完整语法格式如下:
RESTORE DATABASE database_name
[ FROM <backup_device>[,…n] ]
[with
[ FILE=file_number ]
[[,]MOVE ‘logic_file_name’ TO ‘operating_system_file_name’]
[…n]
[[,]{RECOVERY |NORECOVERY }]
[[,] REPLACE ]
[[,] RESTART ]
]
参数说明:
①database_name:指明所要恢复的目标数据库名称。
②FROM
③FILE=file_number:指出从设备上的第几个设备备份中恢复,比如,数据库在同一个备份设备上做了两次备份,恢复第一个备份时应该在恢复命令中使用“FILE=1”选项;恢复第二个备份时应该在恢复命令中使用“FILE=2”选项。
④MOVE ‘logic_file_name’ TO ‘operating_system_file_name’:指定应将给定的logic_file_name(逻辑文件名)移动到operating_system_file_name(物理文件名),默认情况下,logic_file_name将还原到其原始位置。
⑤RECOVERY|NORECOVERY:
如果使用RECOVERY选项,那么恢复完成后,SQL Server将回滚被恢复的数据库中所有未完成的事务,以保持数据库的一致性。在恢复后,用户可以访问数据库了。所以RECOVERY选项用于最后一个备份的恢复。
如果使用NORECOVERY选项,那么SQL Server不回滚被恢复的数据库中所有未完成的事务,在用户恢复结束后,用户不能访问数据库,所以,当不是所要恢复的最后一个备份做恢复时,应使用NORECOVERY。
⑥REPLACE:指明SQL Server创建一个新的数据库,并将备份恢复到这个新的数据库,如果服务器上已经存在一个同名的数据库,则原来的数据库被删除。
⑦RESTART:在上一次恢复操作意外中断时使用,指明此次恢复从上次中断的地方重新开始。
【例】从备份设备score_bak中恢复score数据库。
USE master
GO
RESTORE DATABASE score FROM score_bak
【例】从备份设备file_bak中恢复score数据,并覆盖原数据库。
USE master
GO
RESTORE DATABASE score FROM file_bak
with replace
SQL Server 中的数据传输工具,例如导入与导出,可以将数据从一种数据环境转换为另一种数据环境。它为我们提供了强大、丰富的数据导入导出功能,并且在导入导出的同时可以对数据进行灵活的处理,同时提高数据的安全性。
数据的导入
首先建立一个名为XSCJ的数据库,然后通过下面的步骤把Excel表导入到该数据中。
使用对象资源管理器导入数据的步骤如下:
(1)启动“Microsoft SQL Server Management Studio”,连接到相应的数据库引擎实例。
(2)在“对象资源管理器”中,单击服务器名称以展开服务器目录。
(3)展开“数据库”目录,在XSCJ数据库上单击鼠标右键,弹出快捷菜单,依次选择“任务”、“导入数据”命令。如图10.14所示。
(4)执行“导入数据”命令后,弹出“SQL Server导入和导出向导”窗口,单击“下一步”按钮,进入“选择数据源”窗口,在这里需要导入的是Excel表中的数据,因此在“数据源”下拉列表框中选择“Microsoft Excel” 选项,然后单击“Excel文件路径”后的“浏览”按钮,选择要导入的Excel表格文件,最后在“Excel版本”下拉列表框中选择“Microsoft Excel 97-2005”。 如图10.15所示。
(5)单击“下一步”按钮,弹出如图10.16所示的“选择目标”窗口,用来选择数据所要导入的数据库。在“目标”下拉列表框中选择“Sql Native Client”;然后在“服务器名称”下拉列表框中选择数据库所在的服务器;最后在“数据库”下拉列表框中选择数据库,在这里选择XSCJ数据库。
(6)单击“下一步”按钮,弹出如图10.17所示的“指定表复制或查询”窗口。选中“复制一个或多个表或视图的数据”单选按钮。
(7)单击“下一步”按钮,弹出如图10.18所示的“选择源表和源视图”窗口,用来选择需要复制的表和视图。在这里选择第一个工作薄,同时可以通过编辑进行查看和修改。
(8)单击“下一步”按钮,弹出如图10.19所示的“保存并执行包”窗口,可以调度包的执行时间,这里选择“立即执行”复选框。
(9)单击“下一步”按钮,在弹出的窗口中单击“完成”按钮,即可完成将Excel表导入数据库中。
数据的导出
使用对象资源管理器导入数据的步骤如下:
(1)启动Microsoft SQL Server Management Studio,连接到相应的数据库引擎实例。
(2)在“对象资源管理器”中,单击服务器名称以展开服务器目录。
(3)展开“数据库”目录,在score数据库上单击鼠标右键,弹出快捷菜单,依次选择“任务”、“导出数据”命令。如图10.20所示。
(4)执行“导出数据”命令后,弹出“SQL Server导入和导出向导”窗口,单击“下一步”按钮,进入“选择数据源”窗口,在这里需要导出的是SQL Server数据库中的数据,因此在“数据源”下拉列表框中选择“Sql Native Client” 选项,然后在“服务器名称”下拉列表框中选择数据库所在的服务器;最后在“数据库”下拉列表框中选择数据库,在这里选择score数据库。如图10.21所示
(5)单击“下一步”按钮,弹出“选择目标”窗口,在“目标”下拉列表框中选择“Microsoft Excel ”;然后单击“Excel文件路径”后的“浏览”按钮,选择一个Excel表格文件,最后在“Excel版本”下拉列表框中选择“Microsoft Excel 97-2005”。 弹出如图10.22所示。
(6)单击“下一步”按钮,弹出如图10.23所示的“指定表复制或查询”窗口。选中“复制一个或多个表或视图的数据”单选按钮。
(7)单击“下一步”按钮,弹出如图10.24所示的“选择源表和源视图”窗口,用来选择需要导出的表和视图。在这里选择student表,同时可以通过编辑进行查看和修改。
(8)单击“下一步”按钮,弹出如图10.25所示的“保存并执行包”窗口,可以调度包的执行时间,这里选择“立即执行”复选框。
(9)单击“下一步”按钮,在弹出的窗口中单击“完成”按钮,即可完成将SQL Server数据库中基本表的数据导出到Excel表格中。