第6章Transact-SQL语言简介

6.1 Transact-SQL概述

 Transact-SQL是SQL Server的编程语言,是结构化查询语言(SQL)的增强版本,SQL

是首先由IBM开发的数据库语言。Transact-SQL可用来从数据库中提取数据,执行SQL语言的数据定义(DDL)、数据操作(DML)和数据控制(DCC)等操作。

 本节将介绍Transact-SQL的语法规则和语法元素。

6.1.1Transact-SQL的语法规则

 为了使读者能够方便地阅读本书中关于Transact-SQL的内容,首先介绍Transact-SQL的语法规则,如表6.1所示。

表6.1 Transact-SOL的语法规则

规则

描述

大写

Transact-SQL关键字

斜体

Transact-SQL语法中用户提供的参数

|(竖线)

分隔括号或大括号内的语法项目。只能选择一个项目

[](方括号)

可选语法项目。不必键入方括号

{}(大括号)

必选语法项。不要键入大括号

[, ...n]

表示前面的项可重复n次。每一项由逗号分隔

[ ...n]

表示前面的项可重复n次。每一项由空格分隔

加粗

数据库名、表名、列名、索引名、存储过程、实用工具、数据类型名以及必须按所显示的原样键入的文本

<标签>::=

语法块的名称。此规则用于对可在语句中的多个位置使用的过长语法或语法单元部分进行分组和标记

 除非另外指定,否则所有对数据库对象名的Transact-SQL引用可以是由四部分组成的名称,格式如下:

 [

server_name.[database_name].[owner_name].

 |database_name.[owner_name].

 |owner_name.

]

]

object_name

●server_name指定链接服务器名称或远程服务器名称。

●当对象驻留在SQL Server数据库中时,database_name指定该SQL Server数据库的名称。当对象在链接服务器中时则指定OLE DB目录。

●如果对象在SQL Server数据库中,owner_name指定拥有该对象的用户。当对象在链接服务器中时则指定OLE DB架构名称。

●object_name引用对象的名称。

当引用某个特定对象时,不必总是为SQL Server指定标识该对象的服务器、数据库和所有者。可以省略中间级节点,而使用句点表示这些位置。对象名的有效格式是:

server.database.owner.object

server.database..object

server..owner.object

server..object

database.owner.object

database..object

owner.object

object

 6.1.2Transact-SQL的语法元素

 每一条Transact-SQL语句都包含一系列元素,这些元素可以划分为以下几种情况:

 ●标识符。诸如表、视图、列、数据库和服务器等对象的名称。对象标识符是在定义对象时创建的,标识符随后用于引用该对象。SQL Server的标识符有两类:常规标识符和分隔标识符。

常规标识符符合标识符的格式规则。在Transact-SQL语句中使用常规标识符时不用将其分隔。例如

 SELECT*FROM TableX WHERE KeyCol =124

 在上面的语句中,标识符TableX和KeyCol都是常规标识符·

 分隔标识符包含在双引号(” ”)或者方括号([])内。符合标识符格式规则的标识符可以分隔,也可以不分隔。例如,上面的例子也可以写成

 SELECT*FROM [TableX]WHERE [KeyCol ]=124

其中[TableX]和[KeyCol]都是分隔标识符。

在Transact-SOL语句中,对不符合所有标识符规则的标识符必须进行分隔。例如

SELECT *FROM [ My Table] WHERE [order]=10

[My Table]必须使用分隔标识符,因为My和Table之间有一个空格,如果不进行分隔,SQL Server会把它们看到是两个标识符,从而出现错误。[order]也必须使用分隔标识符,因为order是SQL Server的保留字,用于order by子句。

 常规标识符和分隔标识符包含的字符数必须在1一128之间。对于本地临时表,标识符最多可以有116个字符。

 ●数据类型。定义数据对象(如列、变量和参数)所包含的数据类型。大多数Transact-SQL语句并不显式引用数据类型,但是其结果由于语句中所引用的对象数据类型间的互相作用而受到影响。

 ●函数。与其他程序设计语言中的函数相似,SQL Server函数可以有零个、一个或多个参数,并返回一个标量值或表格形式的值的集合。

 ● 表达式。表达式是SQL Server可解析为单个值的语法单元。例如常量、返回单值的函数、列或变量的引用。

 ● 运算符。运算符中表达式的组成部分之一,它与一个或多个简单表达式一起使用构造一个更为复杂的表达式。例如,将“-”(负号)运算符和常量12组合在一起得到常量-12。

 ● 注释。优秀的程序设计人员,不仅代码写得好,而且会在代码中适当地插入注释。SQL Server将不执行注释的内容。

 SQL Server支持两种类型的注释字符:--(双连字符)和/*…*/(正斜杠一星号对)。

 ---可与要执行的代码处在同一行,也可另起一行。从双连字符开始到行尾均为注释。对于多行注释,必须在每个注释行的开始使用双连字符。例如

 --Choose the pubs database

 USE pubs

 /*…*/可与要执行的代码处在同一行,也可另起一行,甚至在可执行代码内。从开始注释对(/*)到结束注释对(*/)之间的全部内容均视为注释部分。对于多行注释,必须使用开始注释字符对(/*)开始注释,使用结束注释字符对(*/)结束注释。注释行上不应出现其他注释字符。例如

/* Author.Johney Lee

Date:2002-7-16

*/

USE pubs

多行/* */注释不能跨越批处理。整个注释必须包含在一个批处理内。例如,在SQL查询分析器和osql实用工具中,GO命令标志批处理的结束。当实用工具在一行的前两个字节中读到字符GO时,则把从上一GO命令开始的所有代码作为一个批处理发送到服务器。如果GO出现在/*和*/分隔符之间的一行行首,则在每个批处理中都发送不匹配的注释分隔符,从而导致语法错误。

●保留关键字。保留下来由SQL Server使用的词。建议数据库中的对象名不要使用这些字词。如果必须使用保留关键字,则使用分隔标识符。

6.2常量和变量

常量和变量是程序设计过程中必不可少的元素。本节将对Transact-SQL语言的常量和变量进行介绍。

6.2.1常量

 常量,也称为字面值或标量值,是表示一个特定数据值的符号。常量的格式取决于它所表示的值的数据类型。

 Transact-SQL语言的常量包含以下几种类型:

 ●字符串常量。字符串常量包含在单引号内,由字母数字字符(a-z, A-Z和0-9)以及特殊字符( 例如!、@ 和#)组成。例如

‘Process X is 50% complete.’

 如果单引号中的字符串包含一个嵌入的引号,可以使用两个单引号表示嵌入的单引号。对于嵌入在双引号中的字符串则没有必要这样做。例如,字符串I’m Johney可以表示为

‘I’’m Johney’

空字符串用中间没有任何字符的两个单引号表示。

●Unicode字符串常量。Unicode字符串的格式与普通字符串相似,但它前面有一个N标识符(N代表SQL-92标准中的国际语言(National Language)。 N前缀必须是大写字母。例如,’Michel’是字符串常量而N’Michel’则是Unicode常量。

Unicode常量被解释为Unicode数据,并且不使用代码页进行计算。Unicode数据中的每个字符都使用两个字节进行存储,而字符数据中的每个字符则都使用一个字节进行存储。

 ●二进制常量。二进制常量具有前辍0x,并且是十六进制数字字符串。这些常量不使用引号。例如:

OxAE

Ox12Ef

Ox69048AEFDD010E

Ox(空二进制常量)

 ●bit常量。bit常量使用数字0或1表示,并且不使用引号。如果使用一个大于1的数字,它将被转换为1。

 ●datetime常量。datetime常量使用特定格式的字符日期值表示,并被单引号括起来。

例如:

‘April 15,1998’

‘15 April,1998’

‘980415’

‘04/15/98’

‘14:30:24’

‘04:24 PM’

●integer常量。integer常量必须是整数,不能包含小数点。例如:

1894

2

●decimal常量。decimal常量由没有用引号括起来,并且包含小数点的一串数字表示。

例如:

1894.1204

2.0

● float和real常量。float和real常量使用科学记数法表示。例如:

 101.5E5

 101.5E-5

0.5E2

0.5E-2

 ●money常量。money常量表示以可选货币符号作为前缀的一串数字。money常量可以包含小数点,但是不能使用引号。例如:

$12

$542023.14

 ●uniqueidentifier常量。uniqueidentifier常量是表示全局唯一标识符(GUID)值的字符串。可以使用字符或二进制字符串格式指定。例如:

‘6F9619FF-8B86-D011-B42D-00C04FC964FF’

0xff19966f868b11d00c04fc964ff

●指定负数和正数。在数字前面添加+ 或 - ,指明一个数是正数还是负数。例如:

 +145234

 -21483648

 +14534.34

 -214748.10

 +123E-3

 -12E5

-$45.56

 +$423456.99

6.2.2变量

变量对应内存中的一个存储空间。与常量不同,变量的值在程序运行过程中可以随时改变。在Transact-SQL中,包含两种类型的变量:即局部变量和全局变量。

局部变量是用户在程序中定义的变量,它仅在定义的程序范围内有效。局部变量可以用来保存从表中读取的数据,也可以作为临时变量保存计算的中间结果。在批处理和脚本中的变量通常有以下作用:

●作为计数器计算循环执行的次数或控制循环执行的次数;

●保存数据值以供控制流语句测试;

●保存由存储过程返回代码返回的数据值。

 变量只有在声明以后才能被使用。Transact-SQL语言使用DECLARE语句来声明变量。第一次声明变量时将此变量的值设为NULL。 SQL Server支持2种对变量赋值的方法:

 ●使用SET语句;

 ●使用SELECT语句。

 若要通过使用SET语句为变量赋值,请包含变量名和需要赋给变量的值。

 关于DECLARE语句、SET语句和 SELECT语句的具体使用,请参见6.4节。

 全局变量以@@开头,实际上是SQL Server的系统函数。用户可以在程序中,使用全局变量测试系统特性和Transact-SQL命令的执行情况。

6.3运算符与表达式

 运算符是一种符号,用来指定要在一个或多个表达式中执行的操作。SQL Server 2000使用下列几类运算符:

 ●算术运算符;

 ●赋值运算符;

 ●位运算符;

 ●比较运算符;

 ●逻辑运算符;

 ●字符串串联运算符;

 ●一元运算符。

6.3.1算术运算符

 算术运算符在两个表达式上执行数学运算,这两个表达式可以是数字数据类型分类的任何数据类型。SQL Server 2000的算术运算符如表6.2所示。

表6.2                                     算术运算符                          

运算符

描述

+(加号)

加法

-(减号)

减法

*(乘号)

乘法

/(除号)

除法

% (模)

返回一个除法的整数余数。例如,13 % 6=1

6.3.2赋值运算符

Transact-SQL有一个赋值运算符(=)。它通常与SET语句一起使用,为变量赋值。例如:

DECLARE @MyCounter INT

SET @MyCounter=1

6.3.3位运算符

位运算符作用于2个整型数据,对数据进行按位运算。SQL Server 2000的位运算符如表。

6.3所示。

表6.3                          位运算符

运算符

描述

&

按位进行与运算(两个操作数)

|

按位进行或运算(两个操作数)

^

按位进行异或运算(两个操作数)

关于按位进行与运算、或运算和异或运算的计算规则如表6.4所示。

表6.4              按位进行与运算、或运算和异或运算的计算规则

位1

位2

& 运算

| 运算

^ 运算

0

0

0

0

0

0

1

0

1

1

1

0

0

1

1

1

1

1

1

0

6.3.4比较运算符

 比较运算符测试两个表达式是否相同。除了text,、ntext或image数据类型的表达式外,比较运算符可以用于所有的表达式。

 比较运算符的结果是布尔数据类型,它有3种值:TRUE, FALSE及UNKNOWN。SQL Server 2000的比较运算符如表6.5所示。

 表6.5                            比较运算符

运算符

描述

=

等于

大于

小于

>=

大于等于

<=

小于等于

<> 

不等于

!=

不等于

!<

不小于

!>

不大于

6.3.5逻辑运算符

逻辑运算符对某个条件进行测试,以获得其真实情况。逻辑运算符和比较运算符一样,返回带有TRUE或FALSE值的布尔数据类型。

SQL Server 2000的逻辑运算符如表6.6所示。

表6.6                          逻辑运算符

运算符

描述

ALL

如果一系列的比较都为TRUE,那么就为TRUE.例如5>ALL (3, 2, 1)的结果是TRUE;

而5>ALL(3, 6, 2)的结果是FALSE,因为5小于6

AND

如果两个布尔表达式都为TRUE,那么就为TRUE

ANY

如果一系列的比较中任何一个为TRUE,那么就为TRUE。例如5>ANY(3, 6, 8)的结果是TRUE,因为3, 6和8中有一个小于5的数

BETWEEN

如果操作数在某个范围之内,那么就为TRUE. BETWEEN通常与八ND一起使用。例如5 BETWEEN 3 AND 6的结果是TRUE

EXISTS

如果子查询包含一些行,那么就为TRUE

IN

如果操作数等于表达式列表中的一个,那么就为TRUE.例如5 IN(1, 2, 4)的结果是

FALSE,因为5不没有出现在列表中

LIKE

如果操作数与一种模式相匹配,那么就为TRUE.。LIKE子句中会使用%和_等通配符。

_表示一个字符,%表示一个字符串。例如_sql表示在sql前面有一个字符的字符串。对于表达式Varx LIKE _sql来说,当变量Varx符合_sq1的模式,则返回TRUE,否则返回FALSE

NOT

对任何其他布尔运算符的值取反

OR

如果两个布尔表达式中的一个为TRUE,那么就为TRUE

SOME

如果在一系列比较中,有些为TRUE,那么就为TRUE。 SOME与ANY的功能相同

6.3.6字符串串联运算符

字符串串联运算符允许通过加号(+)进行字符串串联,这个加号也被称为字符串串联运算符。其他所有的字符串操作都可以通过字符串函数进行处理。例如:

“abc”+”efg”

的结果是

“abcefg”

6.3.7一元运算符

 一元运算符只对一个表达式执行操作,这个表达式可以是数字数据类型分类中的任何一种数据类型。

 SQL Server 2000的一元运算符如表6.7所示。

 表6.7                        一元运算符

运算符

描述

数值为正

-

数值为负

~

返回数字的补数

6.4常用函数

 函数对于任何程序设计语言都是非常关键的组成部分。Transact-SQL语言为程序员提供了非常丰富函数,足以满足您工作的需要。

 Transact-SQL的函数可以分为以下几类:

 ●聚合函数:

 ●配置函数;

 ●游标函数;

 ●日期和时间函数:

 ●数学函数;

 ●元数据函数;

 ●行集函数;

 ●安全函数;

 ●字符串函数;

 ●系统函数;

 ●系统统计函数;

 ●文本和图像函数。

 由于篇幅所限,本节只能对一些常用的函数进行详细介绍。

6.4.1聚合函数

聚合函数对一组值执行计算并返回单一的值。聚合函数经常与SELECT语句的GROUPBY子句一同使用。

聚合函数及其功能如表6.8所示。

表6.8                          聚合函数及其功能

聚合函数

功能

AVG

返回组中值的平均值

BINARY_CHECKSUM

返回对表中的行或表达式列表计算的二进制校验值

CHECKSUM

返回在表的行上或在表达式列表上计算的校验值。CHECKSUM用于生成哈希索引

CHECKSUM_ AGG

返回组中值的校验值

COUNT

返回组中项目的数量

COUNT_BIG

返回组中项目的数量。COUNT BIG的使用与COUNT函数相似。它们之间的唯一差别是它们的返回值:COUNT_BIG总是返回bigint数据类型值,而COUNT则总是返回int数据类型值

GROUPING

产生一个附加的列,当用CUBE或ROLLUP运算符添加行时,附加的列输出值为1,当所添加的行不是由CUBE或ROLLUP产生时,附加列值为0

MAX

返回表达式的最大值

MIN

返回表达式的最小值

SUM

返回表达式中所有值的和,或只返回DISTINCT值。SUM只能用于数字列

STDEV

返回给定表达式中所有值的统计标准偏差

STDEVP

返回给定表达式中所有值的填充统计标准偏差

VAR

返回给定表达式中所有值的统计方差

VARP

返回给定表达式中所有值的填充的统计方差

请看以下几个常用聚合函数的示例。示例中涉及到的SELECT命令,将在本书第7章中介绍。

注意,读者如果要调试以下示例,可以使用osql实用工具。

● AVG如果要统计员工表Employee中所有员工的平均年龄,请执行以下命令。

USE newdb

SELECT AVG(Age)FROM Employee

GO

运行结果为

--------

 31

(1行受到影响)

● COUNT如果要统计员工表Employee中员工的数量,请执行以下命令

USE nwedb

SELECT COUNT(Emp_id)FROM Employee

GO

运行结果为

--------

12

(1行受到影响)

● MAX如果要统计员工表Employee中的员工最大年龄,请执行以下命令:

USE newdb

SELECT MAX(Age) FROM Employee

GO

运行结果为

-------

42

 (1行受到影响)

● sum如果要统计员工表Employee中的所有员工的工资总数,请执行以下命令:

USE newdb

SELECT SUM(wage) FROM Employee

GO

运行结果为

-------------------------------

41200.00

(1行受到影响)

6.4.2日期和时间函数

日期和时间函数对日期和时间输入值执行操作,并返回一个字符串、数字值或日期和时间值。日期和时间函数及其功能如表6.9所示。

表6-9                    日期和时间函数及其功能

日期和时间函数

功能

DATEADD

在向指定日期加上一段时间的基础上,返回新的datetime值

DATEDIFF

返回跨两个指定日期的日期和时间边界数

DATENAME

返回代表指定日期的指定日期部分的字符串

DATEPART

返回代表指定日期的指定日期部分的整数

DAY

返回代表指定日期的天的日期部分的整数

GETDATE

按datetime值的SQL Server标准内部格式返回当前系统日期和时间

GETUTCDATE

返回表示当前UTC时间(世界时间坐标或格林尼治标准时间)的datetime

值。当前的UTC时间得自当前的本地时间和运行SQL Server的计算机操作系统中的时区设置

MONTH

返回代表指定日期月份的整数

YEAR

返回表示指定日期中的年份的整数

请看以下几个常用日期和时间函数的示例。

● GETDATE如果要查看当前的日期,请执行以下命令:

SELECT GETDATE

GO

运行结果为

-----------

2002-07-22 13:20:42.263

(1行受到影响)

● DATEADD如果要计算当前日期后21天的日期,请执行以下命令:

DECLARE@VarDate datetime

SET @VarDate=GETDATE()

SELECT DATEADD(day,21,@VarDate)

GO

运行结果为

--------------

2002-08-12 13:24:01.650

(1行受到影响)

● DAY如果要提取当前日期的天部分的整数,请执行以下命令:

DECLARE @VarDate datetime

SET @VarDate =GETDATE()

SELECT DAY (@VarDate)

GO

运行结果为

---------

22

(1行受到影响)

6.4.3数学函数

数学函数通常对作为参数提供的输入值执行计算,并返回一个数字值。

数学函数及其功能如表6.10所示。

表6.10                           数学函数及其功能

数学函数

功能

ABS

返回给定数字表达式的绝对值

ACOS

返回以弧度表示的角度值,该角度值的余弦为给定的float表达式;本函数亦称反余弦

ASIN

返回以弧度表示的角度值,该角度值的正弦为给定的float表达式;亦称反正弦

ATAN

返回以弧度表示的角度值,该角度值的正切为给定的float表达式:亦称反正切

ATN2

返回以弧度表示的角度值,该角度值的正切介于两个给定的float表达式之间;亦称反正切

CEILING

返回大于或等于所给数字表达式的最小整数

COS

返回给定表达式中给定角度(以弧度为单位)的三角余弦值

COT

返回给定float表达式中指定角度(以弧度为单位)的三角余切值

DEGREES

当给出以弧度为单位的角度时,返回相应的以度数为单位的角度

EXP

返回所给的float表达式的指数值

FLOOR

返回小于或等于所给数字表达式的最大整数

LOG

返回给定float表达式的自然对数

LOG10

返回给定float表达式的以10为底的对数

PI

返回二的常量值

POWER

返回给定表达式乘指定次方的值

RADIANS

对于在数字表达式中输入的度数值返回弧度值

RAND

返回0~1之间的随机float值

ROUND

返回数字表达式并四舍五入为指定的长度或精度

SIGN

返回给定表达式的正(+1)、零(0)或负(-1)号

SIN

以近似数字(float)表达式返回给定角度(以弧度为单位)的三角正弦值

SQUARE

返回给定表达式的平方

SQR7

返回给定表达式的平方根

TAN

返回输入表达式的正切值

请看以下几个常用数学函数的示例。

● ABS如果要计算一4的绝对值,请执行以下命令:

SELECT ABS(-4)

GO

运行结果为

-------------

4

(1行受到影响)

● CEILING分别对正数、负数和0计算CEILING,请执行以下命令:

SELECT CEILING(12.34),CEILING(-12.34),CEILING(0)

GO

运行结果为

----   --- -  --------

13    –12      0

(1行受到影响)

● ROUND请执行以下命令,注意观察长度变化对结果的影响。

SELECTROUND(123.456,2),ROUND(123.456,1),ROUND(123.456,0),ROUND(123.456,-1),ROUND(123.456,-2), ROUND(123.456,-3)

GO

运行结果为

-----------  ---------  ---------   --------   --------    ---------

123.460  123.500  123.000  120.000  100.000     .000

6.4.4字符串函数

字符串函数对字符串输入值执行操作,返回字符串或数字值。

字符串函数及其功能如表6.11所示。

表6.11             字符串函数及其功能

字符串函数

功能

ASCII

返回字符表达式最左端字符的ASCII代码值

CHAR

将int ASCII代码转换为字符的字符串函数

CHARINDEX

返回字符串中指定表达式的起始位置

DIFFERENCE

以整数返回两个字符表达式的SOUNDEX值之差

LEFT

返回从字符串左边开始指定个数的字符

LEN

返回给定字符串表达式的字符(而不是字节)个数,其中不包含尾随空格

LOWER

将大写字符数据转换为小写字符数据后返回字符表达式

LTRIM

删除起始空格后返回字符表达式

NCHAR

根据Unicode标准所进行的定义,用给定整数代码返回Unicode字符

PATINDEX

返回指定表达式中某模式第一次出现的起始位置;如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零

QUOTENAME

返回带有分隔符的Unicode字符串,分隔符的加入可使输入的字符串成为有效的SQL Server分隔标识符

REPLACE

用第三个表达式替换第一个字符串表达式中出现的所有第二个给定字符串表达式

REPLICATE

以指定的次数重复字符表达式

REVERSE

返回字符表达式的反转

RIGHT

返回字符串中从右边开始指定个数的integer_expressio刀字符

RTRIM

截断所有尾随空格后返回一个字符串

 

SOUNDEX

返回由四个字符组成的代码(SOUNDER)以评估两个字符串的相似性

 

SPACE

返回由重复的空格组成的字符串

 

STR

由数字数据转换来的字符数据

 

STUFF

删除指定长度的字符并在指定的起始点插入另一组字符

 

SUESTRING

返回字符、binary、 text或image表达式的一部分

 

UNICODE

按照Unicode标准的定义,返回输入表达式的第一个字符的整数值

 

UPPER

返回将小写字符数据转换为大写的字符表达式

 

请看以下几个常用字符串函数的示例。

● ASCII请执行以下命令:

SELECT ASCII(‘ABC’)

GO

运行结果为

--------------

65

(1行受到影响)

表明字符A的ASCII码为65。

● CHAR请执行以下命令:

SELECTCHAR(65)

GO

运行结果为

----

 A

(1行受到影响)

● LEFT如果要返回字符串ABCDE的左侧3个字符,请执行以下命令:

SELECT LEFT(’ABCDE’,3)

GO

运行结果为

------

ABC

(1行受到影响)

● LEN如果要返回字符串ABCDE的长度,请执行以下命令:

SELECCT LEN(’ABCDE’)

GO

运行结果为

-------

 5

(1行受到影响)

● LOWER如果要将字符串ABCDE转换为小写字母,请执行以下命令:

SELECT LOWER(’ABCDE’)

GO

运行结果为

-------

abcde

(1行受到影响)

● LTRIM请执行以下命令:

DECLARE @varstr char(50)

SET @varstr=‘abc’

SELECT ‘123’+LTRIM@varstr+’123’

GO

运行结果为

---------------------------------------

123abc

(1行受到影响)

可以看出,只有左侧的空格被删除了。

● REPLACE如果要把字符串ABCDE中的CD替换为123,请执行以下命令:

DECLARE @varstr char(50)

SET @varstr=REPLACE(‘ABCDE’,’CD’,’123’)

SELECT @varstr

GO

运行结果为

-----------------

AB123E

(1行受到影响)

● SPACE请执行以下命令:

DECLARE @varstr char(50)

SET @varstr=‘abc’+SPACE(5)+’123’

SELECT @varstr,LEN @varstr)

GO

运行结果为

-------------------------    --------

Abc      123             11

(1行受到影响)

可以看出,在字符串abc和123之间出现了5个字符串,而字符串的长度为ll。

●STR如果要将计算的结果以字符串的形式显示,请执行以下命令:

DECLARE@varstr decimal(15,2)

SET @varstr=12*4.2

PRINT’12*4.2 的结果是:’+STR@varstr,5,1)

GO

运行结果为

12*4.2的结果是:50.4

●SUBSTRING如果要截取字符串ABCDEFG中第2个字符开始的3个字符,请看以下示例程序:

SELECT SUBSTRING(‘ABCDEFG’,2,3)

GO

运行结果为

------

BCD

(1行受到影响)

● UPPER如果要将字符串ABCDE转换为大写字母,请执行以下命令:

SELECT UPPER(’abcde’)

GO

运行结果为

--------

ABCDE

(1行受到影响)

6.4.5文本和图像函数

文本和图像函数对文本或图像输入值或列执行操作,返回有关这些值的信息。

文本和图像函数及其功能如表6.12所示。

表6.12                 文本和图像函数及其功能

文本和图像函数

功能

PATINDEX

返回指定表达式中某模式第一次出现的起始位置;如果在全部有效的文本和字符数据类型中没有找到该模式,则返回零

TEXTPTR

以varbinary格式返回对应于text, next或image列的文本指针值。检索到的文本指针值可用于READTEXT, WRITETEXT和UPDATETEXT语句

TEXTVALID

一个text、ntext或image函数,用于检查给定文本指针是否有效

第7章Transact-SQL数据库操作语句

7.1数据库管理语句

在第4章中,读者己经了解了SQL Server数据库的创建和维护。但是这些数据库操作都是在SQL Server企业管理器中手工进行的。这种操作方式非常简单直观,便于学习和掌握。但是,它不能将工作的过程保存下来,每次操作都需要重复进行,操作量大的时候不易使用。

在很多情况下,需要在程序或脚本中完成对数据库的操作。Transact-SQL提供了数据库管理语句,包括创建数据库、修改数据库、删除数据库、分离数据库和附加数据库等等。

7.1.1创建数据库语句CREATE DATABASE

CREATE DATABASE语句的功能是创建一个新数据库及存储该数据库的文件,或从先前创建的数据库文件中附加数据库。

在创建数据库时,有时需要定义存储该数据库的文件。所以在介绍CREATE DATABASE语句之前,应该首先了解文件<filespec>和文件组<filegroup>的语法。

<filespec>的语法结构如下:

<filespec>::=

[PRIMARY]

([NAME=logical_file_name,]

 FILENAME=‘os_file_name’

 [,SIZE=size]

 [,MAXSIZE={max_size|UNLIMITED}]

 [,FILEGROWTH=growth_increment])[,…n]

 参数说明如下:

 ●  定义主文件〔PRIMARY ]。 PRIMARY指定关联的<filespec>列表定义主文件。主

文件组包含所有数据库系统表。还包含所有未指派给用户文件组的对象。主文件组的第一个<filespec>条目成为主文件,该文件包含数据库的逻辑起点及其系统表。一个数据库只能有一个主文件。如果没有指定PRIMARY那么CREATE  DATABASE语句中列出的第一个文件将成为主文件。

●  指定逻辑名称[NAME=logical_file_name,]。NAME为由<filespec>定义的文件指定逻辑名称。

logical_file_name用来在创建数据库后执行的Transact-SQL语句中引用文件的名称。logical_file_ name在数据库中必须唯一,并且符合标识符的规则。

●  指定操作系统文件名FILENAME=‘os_file_ name’。FILENAME为<filespec>定义的文件指定操作系统文件名。

‘os_f:ile_name’是操作系统创建<filespec>定义的物理文件时使用的路径名和文件名。os_file_ name中的路径必须指定SQL Server实例上的目录。os_file _name不能指定压缩文件系统中的目录。

●  定义文件大小〔,SIZE二size}。SIZE指定<filespec>中定义的文件的大小。如果主文件的<filespec>中没有提供SIZE参数,那么SQL Server将使用model数据库中的主文件大小。如果次要文件或日志文件的<filespec>中没有指定SIZE参数,则SQL Server将使文件大小为1 MB。

Size是<filespec>中定义的文件的初始大小。可以使用千字节(KB)、兆字节(MB)、千兆字节(GB)或兆兆字节(TB)后缀。默认值为MB。指定一个整数,不要包含小数位。size的最小值为512 KB。如果没有指定size,则默认值为1 MB。为主文件指定的大小至少应与model数据库的主文件大小相同。

●  定义文件的最大尺寸[,MAXSIZE={max_size I UNLIMITED}]。MAXSIZE指定<filespec>中定义的文件可以增长到的最大大小。

max­_size是<filespec>中定义的文件可以增长到的最大大小。可以使用千字节(KB),兆字节(MB)、千兆字节(GB)或兆兆字节(TB)后缀。默认值为MB。指定一个整数,不要包含小数位。如果没有指定max_srze,那么文件将增长到磁盘变满为止。

●  UNLIMITED参数。UNLIMITED指定<filespec>中定义的文件将增长到磁盘变满为止。

●定义文件的增长增量[,FILEGROWTH=growth_increment]。FILEGROWTH指定<filespec>中定义的文件的增长增量。文件的FILEGROWTH设置不能超过MAXSIZE设置。

growth_increment是每次需要新的空间时为文件添加的空间大小。指定一个整数,不要包含小数位。0值表示不增长。该值可以MB, kB, GB, TB或百分比(%)为单位指定。如果未在数量后面指定MB, kB或%,则默认值为MB。如果指定%,则增量大小为发生增长时文件大小的指定百分比。如果没有指定FILEGROWTH,则默认值为10%,最小值为64kB。指定的大小舍入为最接近的64 kB的倍数。

<filegroup>的语法结构如下:

<fileguoup>::=

FILEGROUP filegroup_name<filespec>[,…n]

在CREATE  DATABASE语句中,将使用<filespec>R<filegroup>来描述数据库文件。

CREATE  DATABASE的语法结构如下:

CRETE DATABASE datebase_name

[ON

 [<filespec>[,…n]

 [,<filegroup>[,…n]]

]

[LOGON{<filespec>[,…n]}]

[COLLATE collation_name]

[FOR LOAD|FOR ATTACH]

下面,依次介绍各参数的使用情况。

●  指定数据库名称database_name. database_name是新数据库的名称。数据库名称在

服务器中必须唯一,并且符合标识符的规则。例如,要创建一个名为mytest的数据库,可以使用以下命令:

 CREATE DATABASE mytest

因为没有设置其他参数,所以其他选项均为默认值。

●  设置存储数据库的磁盘文件。ON指定用来存储数据库数据部分的磁盘文件(数据文件)。该关键字后跟以逗号分隔的<filespec>项列表,<filespec>项用以定义主文件组的数据文件。主文件组的文件列表后可跟以逗号分隔的<filegroup>项列表,<filegroup>项用以定义用户文件组及其文件。n占位符表示可以为新数据库指定多个文件。

请看下面的示例:

USE master

GO

CREATE DATABASE Archive

ON

PRIMARY (NAME=Arch1,

 FILENAME='c:\program files\microsoft sql server\mssql\data\archdqt1.mdf',

 SIZE=100MB,

 MAXSIZE=200,

 FILEGROWTH=20),

(NAME= Arch2,

FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt2.mdf ',

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20),

(NAME=Arch3,

FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt3.mdf ',

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20)

在创建数据库时,指定了存储数据库的文件组。在osql中运行上面的代码,结果为:

------------------------------

CREATE DATABASE 进程正在磁盘’Arch1’上分配 100.00MB的空间。

CREATE DATABASE 进程正在磁盘’Arch2’上分配 100.00MB的空间。

CREATE DATABASE 进程正在磁盘’Arch3’上分配 100.00MB的空间。

-------------------------------

在企业管理器中,可以看到新建的数据库Archive.右击数据库Archive,选择“属性”命令,打开"Archive属性”对话框。选择“数据文件”选项卡,就可以看到数据文件的设置情况,与Transact-SQL指令的要求完全相同,如图7.1所示。

图7.1检查数据库创建后的数据文件

●  设置存储数据库日志的磁盘文件。LOG ON指定用来存储数据库日志的磁盘文件。该关键字后跟以逗号分隔的<filespec>项列表,<filespec>项用以定义日志文件。如果没有指定LOG ON,将自动创建一个日志文件,该文件使用系统生成的名称,大小为数据库中所有数据文件总大小的25%。

例如上面的示例程序如果增加数据库日志部分的设置,将变成以下内容:

USE master

GO

CREATE DATABASE Archive

ON

PRIMARY (NAME =Arch1,

 FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt1.mdf ',

 SIZE=100MB,

 MAXSIZE=200,

 FILEGROWTH=20),

(NAME=Arch2,

 FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt2.mdf ',

 SIZE=100MB,

 MAXSIZE=200,

 FILEGROWTH=20),

(NAME=Arch3,

 FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt3.mdf ',

 SIZE=100MB,

 MAXSIZE=200,

 FILEGROWTH=20)

LOG ON

(NAME=Archlog1,

FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt1.mdf ',

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20),

(NAME=Archlog2,

FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt2.mdf ',

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20)

GO

增加了两个日志文件,Archlog 1和Archlog2o运行结果为:

------------------

CREATE DATABASE 进程正在磁盘 'Arch1' 上分配 100.00 MB 的空间。

CREATE DATABASE 进程正在磁盘 'Arch2' 上分配 100.00 MB 的空间。

CREATE DATABASE 进程正在磁盘 'Arch3' 上分配 100.00 MB 的空间。

CREATE DATABASE 进程正在磁盘 'Archlog1' 上分配 100.00 MB 的空间。

CREATE DATABASE 进程正在磁盘 'Archlog2' 上分配 100.00 MB 的空间。

-------------------

在企业管理器中,右击数据库Archive,选择“属性”命令,打开“Archive属性”对话框。选择“事务日志”选项卡,就可以看到日志文件的设置情况,与Transact-SQL指令的要求完全相同,如图7.2所示。

图7.2检查数据库创建后的日志文件

●排序规则。COLLATE子句的功能是定义排序规则,或应用于字符串表达式以应用排序规则投影。collation_name指定数据库的默认排序规则。排序规则名称既可以是Windows排序规则名称,也可以是SQL排序规则名称。如果没有指定排序规则,则将SQL Server实例的默认排序规则指派为数据库的排序规则。

●  FOR LOAD子句。FOR LOAD子句是为了与早期版本的SQL Server兼容。数据库在打开dbo use only数据库选项的情况下创建,并且将其状态设置为正在装载。SQL Server 7.0版中不需要该子句,因为RESTORE语句可以作为还原操作的一部分重新创建数据库。

●  附加数据库。FOR ATTACH指定从现有的一组操作系统文件中附加数据库。必须有指定第一个主文件的<filespec>条目。至于其他<filespec>条目,只需要与第一次创建数据库或上一次附加数据库时路径不同的文件的那些条目。必须为这些文件指定<filespec>条目。附加的数据库必须使用与SQL Server相同的代码页和排序次序创建。通常应使用sp attach- d6系统存储过程,而不要直接使用CREATE DATABASE FOR ATTACH.只有必须指定16个以上的<filespec>项目时,才需要使用CREATE DATABASE FOR ATTACH。

请看以下示例程序:

sq_detach_db Archive

GO

CREATE DATABASE Archive

ON PRIARY(FILENAME= ‘c:\program files\microsoft sql server\mssql\data\archdqt1.mdf’)

FOR ATTACH

GO

这段程序的作用是首先将数据库Archive分离,然后再通过附加数据库操作将其恢复。存储过程sp_detach_db的作用是分离数据库。

7.1.2修改数据序语句ALTER DATABASE

使用ALTER DATABASE语句可以在数据库中添加或删除文件和文件组。也可以用来更改文件和文件组的属性,例如更改文件的名称和大小。ALTER DATABASE提供了更改数据库名称、文件组名称以及数据文件和日志文件的逻辑名称的能力。

ALTER DATABASE语句的语法结构如下:

ALTER DATABASE database

{ADD FILE <filespec>[,…n][TO FILEGROUP filegroup_name]

|ADD LOG FILE logical_file_name

|REMOVE FILE logical_file_name

|ADD FILEGROUP filegroup_name

|REMOVE FILEGROUP filegroup_name

|MODIFY FILE<filespec>

|MODIFY NAME=new_dbname

|MODIFY FILEGROUP filegroup_name {filegroup_property|NAME=new_filegroup_name}

|SET<optionspec>[,…n][WITH<termination>]

|COLLATE<collation_name>

}

参数说明如下:

●  指定数据库名称database。 database是要更改的数据库的名称。

●  指定要添加的文件。ADD FILE子句表示要添加文件。TO FILEGROUP子句指定要将指定文件添加到的文件组。filegroup_name是要添加指定文件的文件组名称。

例如要在数据库Archive中添加一个文件Arch4,可以使用以下命令:

ALTER DATABASE Archive

ADD FILE

(NAME=Arch4,

FILENAME=' c:\program files\microsoft sql server\mssql\data\archdqt4.mdf ',

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20)

GO

运行结果显示:

以100.00MB为单位在磁盘 ‘Arch4’上扩展数据库。

检查“Archive属性”对话框,在“数据文件”选项卡中,可以看到Arch4,如图7.3所示。

图7.3使用ALTER DATABASE语句添加的Arch4

●  添加日志文件。ADD LOG FILE子句指定要将日志文件添加到指定的数据库。

例如要在数据库Archive中添加一个日志文件Archlog3,可以使用以下命令:

ALTER DATABASE Archive

ADD LOG FILE

(NAME =Archlog3,

FILENAME = ‘c:\program files\microsoft sql server \mssql\data\archlog3.ldf,

SIZE=100MB,

MAXSIZE=200,

FILEGROWTH=20)

GO

运行结果显示:

以100.00MB为单位在磁盘 ‘Archlog3’上扩展数据库。

同样可以在"Archive属性”对话框的“事务日志”选项卡中看到新增的Archlog3o

●   删除文件。REMOVE FILE从数据库系统表中删除文件描述并删除物理文件。只有在文件为空时才能删除。

例如要将Arch4从Archive数据库中删除,可以使用以下命令:

ALTER DATABASE Archive

REMOVE FILE arch4

GO

运行结果显示:

文件’arch4’已删除。

●  添加文件组。ADD FILEGROUP子句指定要添加文件组。filegroup_name是要添加的文件组名称。

●  删除文件组。REMOVE FILEGROUP子句从数据库中删除文件组并删除该文件组中的所有文件。

●  修改文件。MODIFY FILE子句指定要更改给定的文件,更改选项包括FILENAME,SIZE, FILEGROWTH和MAXSIZE。一次只能更改这些属性中的一种。必须在<filespec>中指定NAME,以标识要更改的文件。如果指定了SIZE那么新大小必须比文件当前大小要大。只能为tempdb数据库中的文件指定FILENAME,而且新名称只有在SQL Server重新启动后才能生效。

例如,要把数据库Archive中的Arch3的文件大小更改为200MB,可以使用以下命令:

ALTER DATABASE Archive

MODIFY FILE

(NAME=Arch3,

SIZE=200MB)

 GO

●  重命名数据库。MODIFY NAME=new_dbname子句用来重命名数据库。

●  修改文件组。MODIFY FILEGROUP filegroup_name{filegroup_property|NAME=new _filegroup_name}指定要修改的文件组和所需的改动。如果指定filegroup_name和NAME=new filegroup_name,则将此文件组的名称改为new filegroup_name。如果指定filegroup_name和filegroup_property ,则表示给定文件组属性将应用于此文件组。

filegroup_property的值请参见表7.1。

表7.1          MODIFY FILEGROUP子句中filegroup_property的值

描述

READONLY

指定文件组为只读。不允许更新其中的对象。主文件组不能设置为只读。只有具有排它数据库访问权限的用户才能将文件组标记为只读

READWRITE

逆转READONLY属性。允许更新文件组中的对象。只有具有排它数据库访问权限的用户才能将文件组标记为读/写

DEFAULT

将文件组指定为默认数据库文件组。只能有一个数据库文件组是默认的

●  数据库排序规则;COLLATE<collation_name>子句指定数据库的排序规则。排序规则名称既可以是Windows排序规则名称,也可以是SQL排序规则名称。如果没有指定排序规则,则将SQL Server实例的默认排序规则指派为数据库的排序规则。

●   设置选项。SET子句用来设置修改数据库的选项。这些选项可以分为以下几类:

口  状态选项<state_option>:控制用户对数据库的访问,数据库是否处于联机状态,以及是否允许写操作;

口  控制游标选项<cursor_option>;

口  控制自动选项<auto_option>;

口  控制ANSI遵从性选项<sql_option>;

口  控制数据库恢复选项<recovery_options>。

 SET选项的描述如表7.2所示。

 表7.2                                 SET子句的选项                                              

分类

选项

描述

状态选项

SINGLE_USER

同一时间只能有一个用户访问数据库

状态选项

RESTRICTED_USER

只有db _owner、 dbcreator或sysadmin角色的

成员可以使用数据库

状态选项

MULTI_USER

使数据库返回到正常操作状态

状态选项

OFFLINE

控制数据库是脱机

状态选项

ONLINE

控制数据库是联机

状态选项

READ_ONLY

在只读模式下,用户可以从数据库中读取数据,但不能修改数据。当指定READ_ONLY时,数据库不能处于使用状态

状态选项

READ_WRITE

使数据库返回到读写操作状态

控制游标选项

CURSOR_CLOSE_ON_COMMIT  ON|OFF

如果指定为ON,在事务提交或回滚时所有打开的游标都将关闭。如果指定为OFF,那么在事务提交时打开的游标仍保持打开;而回滚事务时关闭所有除定义为INSENSITIVE或STATIC之外的游标

控制游标选项

CURSOR_DEFAULTLOCAL|

GLOBAL

控制游标作用域默认为LOCAL还是GLOBAL

控制自动选项

AUTO_ CLOSE ON|OFF

如果指定为ON,那么最后一个用户退出后,数据库将干净地关闭,其占用的资源将释放。如果指定为OFF,那么最后一个用户退出后数据库仍保持打开

控制自动选项

AUTO_CREATE _STATISTICS ON|OFF

如果指定为ON,那么所有优化查询需要但缺少的统计信息都会在查询优化时自动生成

控制自动选项

AUTO_SHRINK ON|OFF

如果指定为ON,数据库文件将定期自动收缩

控制自动选项

AUTO_UPDATE_STATISTICS ON|

OFF

如果指定为ON,所有查询优化所需的过时的统计信息在都将在优化时自动重建。如果指定为OFF,统计信息必须手工更新

控制人NSI遵从

性选项

ANSI_NULL_DEFAULT ON|OFF

如果指定为ON,CREATE TABLE在确定列是

否允许空值时遵从SQL-92规则

控制ANSI遵从

性选项

ANSI_ NULLS ON| OFF

如果指定为ON,所有与空值的比较运算结果为UNKNOWN.如果指定为OFF,非UNICODE值与空值的比较运算在两者均为NULL时结果为TRUE

控制ANSI遵从

性选项

ANSI_WPADDING ON|OFF

如果指定为ON,在比较或插入前,字符串将填充为同一长度。如果指定为OFF,字符串将不填充

控制ANSI遵从

性选项

ANSI _WARNINGS ON|OFF

如果指定为ON,当出现诸如被零除的情况时将产生错误或警告

控制ANSI遵从

性选项

ARITHABORT ON|OFF

如果指定为ON,在执行查询时如果发生溢出或被零除,该查询将终止

控制ANSI遵从

性选项

CONCAT_NULL_YIELDS_NULL

ON|OFF

如果指定为ON,当串联操作的两个操作数中任意一个为NULL时,结果也为NULL.如果指定为OFF,空值将按空字符串对待。默认设置为OFF

控制ANSI遵从

性选项

QUOTED_ IDENTIFIER ON|OFF

如果指定为ON,双引号将可用于包含定界标识符

控制人NSI遵从

性选项

NUMERIC _ROUNDABORT ON|

OFF

如果指定为ON,当表达式中出现精度损失时将产生错误

控制ANSI遵从

性选项

RECURSIVE_TRIGGERS ON|

OFF

如果指定为ON,将允许递归激发触发器。

RECURSIVE TRIGGERS OFF(默认值)只禁止直接递归。若要也禁用间接递归,请使用sp_configure将nested triggers服务器选项设置为0

控制数据库恢复选项

RECOVERY FULL

系统将对介质错误提供完全保护。如果数据文件损坏,介质恢复可以还原所有己提交的事务

控制数据库恢复选项

RECOVERY BULK_LOGGED

将在介质错误保护程度与某些大规模或大容量操作的最优性能及日志存储空间最少占用量之间进行权衡

控制数据库恢复选项

RECOVERY SIMPLE

系统将提供占用日志空间最小的备份策略。服务器故障恢复不再需要的日志空间可被自动重用。简单恢复模型比其他两种模型更容易管理,但数据文件损坏时造成数据丢失的可能性更大

控制数据库恢复选项

TORN_PAGE_DETECTION ON|OFF

如果指定为ON,将可以检测到未完成的页。默认设置为ON

7.1.3删除数据库语句DROP DATABASE

DROP DATABASE语句从SQL Server中删除一个或多个数据库。删除数据库将删除数据库所使用的数据库文件和磁盘文件。

DROP DATABASE语句的语法结构如下:

DROP DATABASE database_name[,…n]

database_name指要删除的数据库名称。可以同时删除多个数据库。

例如,要将数据库Archive删除,可以执行以下命令:

DROP DATABASE Archive

GO

运行结果为:

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog3.ldf’ 。

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog2.ldf’ 。

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog3.ldf’ 。

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog2.ldf’ 。

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog1.ldf’ 。

正在删除数据文件’c:\program files\Microsoft sql server\mssql\data\archlog1.ldf’ 。

体现了删除数据库文件的过程。

7.1.4分离数据库语句sp_detach_db

sp _detach_db实际上是一个存储过程,它的功能是从服务器分离数据库。Sp_detach_db语向的语法结构如下:

sp_detach_db[@dbname]= ‘dbname’

[,[@skipchecks=]’skipchecds’]

参数说明如下:

● [@dbname =] ‘dbname’ 。表示要分离的数据库名称。dbname的数据类型为sysname,

默认值为NULL。

●「 @skipchecks=〕’sldpchecks’。定义是否执行UPDATE STATISTICS。sldpchecks的数据类型为nvarchar(10),默认值为NULL。如果为true,则跳过UPDATE STATISTICS。如果为false,则运行UPDATE STATISTICS。对于要移动到只读媒体上的数据库,此选项很有用

如果要将数据库Archive分离,请执行以下命令:

EXEC sp_detach_db’Archive’,’true’

EXEC命令的功能是执行存储过程。

7.1.5附加数据库语句sp_attach_db

sp _attach _db也是一个存储过程,它的功能是将数据库附加到服务器上。sp_attach_db语句的语法结构如下:

参数说明如下:

●[@dbname月’dbname’ 。指定要附加到服务器的数据库的名称。该名称必须是唯一的。dbname的数据类型为sysname,默认值为NULL。

●[@filenamel=]filename_n’。指定数据库文件的物理名称,包括路径。filename_n的数据类型为nvarchar(260),默认值为NULL.最多可以指定16个文件名。

请看下面的示例程序:

EXEC sp_attach_db @dbname=N’pubs’,

@filename1=N ‘c:\Program Files\Microsoft SQL Server \MSSQL\Data\pubs.mdf,

@filename2=N ‘c:\Program Files\Microsoft SQL Server\MSSQL\Data\pubs_log.ldf

7.2表管理语句

 

表是数据库中最常用的元素,表的管理包括创建表、修改表和删除表等。

7.2.1创建表语句CREATE TABLE

CREATE TABLE语句的功能是在数据库中创建新表。CREATE TABLE语句的语法结构比较复杂,所以我们首先了解一种最简单的情况。

CREATE TABLE 表名

 (列名 1    数据类型,

列名 2    数据类型,

……

列名n     数据类型

例如创建一个数据库TestDB,并在TestDB中创建表Employee,可以使用以下示例程序:

CREATE DATABASE TestDB

GO

USE TestDB

CREATE TABLE Employee

(Emp_Id                  SMALLINT,

Emp_Name                VARCHAR(50),

Sex                       CHAR(2),

Age                       SMALLINT,

Title                       VARCHAR(50),

Office_phone                VARCHAR(30),

Mobile_phone                VARCHAR(30),

Id_Card                     VARCHAR(30),

Wage                       DECIMAL(18,2),

Dep_Id                      TINYINT

)

GO

●  表名的定义。在上面的示例中,表名为Employee,这是最简单的定义表名的方式。

在CREATE TABLE语句中,共有以下3种定义表名的方式:

 口CREATE TABLE表名。例如CREATE TABLE Employee;

 口CREATE TABLE数据库名.表名。例如CREATE TABLE TestDB.Employee;

 口CREATE TABLE数据库名.属主名.表名。例如CREATE TABLE

TestDB.dbo.Employee。

 ●  NULL/NOT NULL。 NULL和NOT NULL参数设置列的空与非空。如果希望某一列必须有数据,则在该列的定义后加上NOT NULL参数。默认情况下,允许列为空,所以不必在列定义后添加NULL参数。

 如果需要将Emp_Name列定义为非空,可以使用以下代码:

CREATE TABLE Employee

(Emp_Id             SMALLINT,

Emp _Name          VARCHAR(50)   NOT NULL

……

)

 ●  PRIMARY KEY约束。PRIMARY KEY参数定义表的主键。定义主键可以确保列的唯一性,一张表中只能存在一个主键。定义主键的基本语法为:

[CONSTRAINT constraint _name] PRIMARY KEY [CLUSTERED|NONCLUSTERED]

CONSTRAINT是可选关键字,表示PRIMARY KEY、NOT NULL等约束定义的开始。用户可以自定义约束的名称,也可以由系统默认提供约束名。

CLUSTERED|NONCLUSTERED表示为PRIMARY KEY约束创建聚集或非聚集索引的关键字。聚集索引确定表中数据的物理顺序,对于那些经常要搜索范围值的列特别有效。

PRIMARY KEY约束默认为CLUSTERED

例如,如果将Emp_Id列定义为主键可以使用以下代码:

CREATE TABLE Employee

(Emp_Id         SMALLINT      PRIMARY    KEY   CLUSTERED,

Emp_Name       VARCHAR(50)   NOTNULL

……

)

如果需要自定义主键名,请使用以下代码:

CREATE TABLE Employee

(Emp_Id                SMALLINT

 CONSTRAINT PK_Emp_Id PRIMARY KEY CLUSTERED,

Emp_Name              VARCHAR(50)      NOT NULL

……

)

●  UNIQUE约束。由于一个表中只能存在一个主键,所以如果需要对其他的列进行唯一性约束,只能使用UNIQUE约束。与PRIMARY KEY约束不同,UNIQUE约束允许NULL值的列。

定义UNIQUE约束的基本语法为:

[CONSTRAINT constraint_name] PRIMARY KEY [CLUSTERED |NONCLUSTERED]

如果定义员工身份证号码列Id_Card为UNIQUE约束,可以使用以下代码:

CREATE TABLE Employee

(Emp_Id        SMALLINT         PRIMARYKEY CLUSTERED,

Emp_Name      VARCHAR(50)      NOT NULL

……

Id_Card         VARCHAR(30)      UNIQUE   NONCLUSTERED,

……

)

也可以使用用户自定义名称的方式,代码如下:

CREATE TABLE Employee

(Emp_Id        SMALLINT        PRIMARYKEY CLUSTERED,

Emp_Name      VARCHAR(50)     NOT NULL

……

Id_Card         VARCHAR(30)

 CONSTRAINT U_Id_Card UNIQUE NONCLUSTERED,

……

)

●   FOREIGN KEY约束。FOREIGN KEY约束用来定义表的外键。FOREIGN KEY与REFERENCES相结合使用。

定义FOREIGN KEY约束的基本语法为:

[CONSTRAINT constraint_name] FOREING KEY [(column[,…n])] REFERENCES ref_table [(ref_column[,…n])]

如果在Employee表的Dep_Id列和Department表的Dep_Id列之间建立FOREIGN KEY约束,可以使用以下代码:

CREATE TABEL Employee:

(Emp_Id         SMALLINT        PRIMARY KEY CLUSTERED,

Emp_Name      VARCHAR(50)      NOT NULL

……

Dep_ld         TINYINT      NOT NULL

PEFERENCES Department(Dep_Id)

)

在对单列之间建立外键时,可以省略FOREIGN KEY。

●  CHECK约束。CHECK约束通过限制可输入到一列或多列中的可能值强制域完整性的约束。

定义CHECK约束的基本语法为:

[CONSTRAINT constraint_name]CHECK[NOT FOR REPLICATION ] (search_conditions)

如果要求所有员工的年龄大于18岁,则可以对Age列使用CHECK约束,代码如下:

CREATE TABLE Employee

(Emp_Id       SMALLINT      PRIMARYKEYCLUSTERED,

Emp_Name     VARCHAR(50)   NOTNULL

Sex            CHAR(2),

Age            SMALLINT

CHECK(Age>18),

……

)

● DEFAULT定义。DEFAULT定义可以指定列的默认值。在对表执行INSERT或UPDATE指令时,如果没有指定该的值,则将该列赋值为默认值。

如果要把Title列的默认值设置为,职员’,可以使用以下代码:

CREATE TABLE Employee

(Emp_Id         SMALLINT       PRIMARY  KEY  CLUSERED,

Emp_Name       VARCHAR(50)    NOT NULL

Sex             CHAR(2),

Age             SMALLINT,

Title            VARCHAR(50)

DEFAULT(‘职员’)

……

)

●  计算列。计算列是物理上并不存储在表中的虚拟列。计算列由同一表中的其他列通过表达式计算得到。在对表使用INSERT或UPDATE指令时,不能对计算列进行赋值。

表Employee中没有计算列。可以增加“年薪”列YearSalary, YearSalary=Wage*120创建表的代码如下:

CREATE TABLE Employee

(Emp_Id        SMALLINT       PRIMARY KYE  CLUSTERED,

Emp_Name      VARCHAR(50)    NOT NULL

Sex             CHAR(2),

Age            SMALLINT,

Title            VARCHAR(50)

……

Wage           DECIMAL(18,2),

YearSalary AS Wage *12

……

)

以上介绍的只是CREATE TABLE语句中常用的关键字,如果读者需要了解CREATETABLE语句更多的使用方法,请查阅SQL Server的联机帮助。

7.2.2修改表语句ALTER TABLE

使用ALTER TABLE语句可以更改、添加、除去列和约束,或者通过启用或禁用约束和触发器来更改表的定义。本节将简单地介绍ALTER TABLE的使用情况。

●添加列。可以在ALTER TABLE语句中使用ADD子句来添加列。例如:

ALTER TABLE TestTable ADD column_b VARCHAR(20)

是在表TestTable中添加列colurnn_b。

●删除列。在ALTER TABLE语句中使用DROP COLUMN子句,可以删除列或约束。

例如:

ALTER TABLE TestTable DROP COLUMN column_b

是从表TestTable中将column_b列删除。

●添加约束。如果在创建表时,没有对某一列设置约束,则可以通过ALTER TABLE

 的ADD CONSTRAINT子句设置。例如:

ATTER TABLE Employee ADD CONSTRAINT

PK_Emp_Id PRIMRY KEY NONCLUSTERED (Emp_Id)

●删除约束。使用ALTER TABLE语句的DROP CONSTRAINT子句可以删除己有的约束。例如:

ALTER TABLE Employee DROP CONSTRAINT PK_Emp_Id

● NOCHECK选项。如果只是暂停某一约束的作用,而并不想真正地删除此约束,可以使用NOCHECK关键字。例如:

ALTER TABLE Employee NOCHECK CONSTRAINT PK_Emp_Id

如果要恢复被暂停的约束,只需使用CHECK关键字。例如

在有些情况下,用户需要对某一列追加约束,但是此列中存在不符合约束的数据。为了在添加约束的同时,不影响原有的数据,请使用WITH NOCHECK关键字。例如

ALTER TABLE Employee WITH NOCHECK

ADD CONSTRAINT CK_Age CHECK(Age>18)

ALTER TABLE语句的功能非常强大,语法结构也比较复杂。但是它的很多子句与CREATE TABLE中的使用方法相近,本书将不再进行详细地论述。

7.2.3删除表语句DROP TABLE

DROP TABLE语句的作用是删除表定义及该表的所有数据、索引、触发器、约束和权限规范。不能使用DROP TABLE来删除系统表。

DROP TABLE的语法结构非常简单:

DROPTABLE table_name

其中table_name为要删除的表名。

7.3索引管理语句

使用Transact-SQL语句可以创建和删除索引。

7.3.1创建索引语句CREATE INDEX

CREATE INDEX语句的功能是为给定的表或视图创建索引。它的语法结构如下:

CREATE [UNIQUE][CLUSTERED|NOUCLUSTERED]INDEX index_name

ON {table|view}(column[ASC|DESC][,…n])

[WITH<index_option>[,…n]]

[ON filegroup]

参数说明如下:

●  必需参数。使用CREATE INDEX语句的最简单格式为:

CREATE INDEX<索引名>ON<表名>|<视图名>(列名)

例如为表Employee创建基于Wage列的索引au_wage,可以使用以下命令:

CREATE INDEX au_wage ON Employee(wage)

●  唯一索引。使用UNIQUE参数创建唯一索引。在创建唯一索引时,如果数据已存在,SQL Server会检查是否有重复值,并在每次使用INSERT或UPDATE语句添加数据时进行这种检查。如果存在重复的键值,将取消CREATE INDEX语句,并返回错误信息,给出第一个重复值。

例如为表Employee创建基于Id_Card列的唯一索引au_Id_Card,可以使用以下命令:

CREATE UNIQUE INDEX au_Card ON Employee(Id_Card)

●  聚集/非聚集索引。使用CLUSTERED和NONCLUSTERED参数创建聚集和非聚集索引。聚集索引行的物理排列次序与索引排序相同,从而大大地提高了搜索的效率。一个表或视图只允许有一个聚集索引。在不使用CLUSTERED/NOCLUSTERED的情况下,默认为非聚集索引。

CLUSTERED/NOCLUSTERED可以和UNIOUE同时出现。请看下面的示例:

CREATE UNIQUE CLUSTERED INDEX au_Id_Card ON Employee(Id_Card)

●  升序和降序。使用ASC和DESC参数来确定具体某个索引列的升序或降序排序方向。默认设置为ASC。

如果要对表Employee的Wage列按照降序创建索引,可以使用以下命令:

CREATE INDEX au_wage ON Employee(wage DESC)

●WITH子句。WITH子句用来设置索引选项。CREATE INDEX支持的索引选项如表7.3所示。

表7.3                    WITH子句支持的索引选项

选项

描述

PAD_INDEX

指定索引中间级中每个页(节点)上保持开放的空间。PAD_INDEX

项只有在指定了FILLFACTOR时才有用,因为PAD INDEX使用由

FB.LFACTOR所指定的百分比

FILLFACTOR = fillfactor

指定在SQL Server创建索引的过程中,各索引页叶级的填满程度

IGNORE_DUP_ KEY

控制当尝试向属于唯一聚集索引的列插入重复的键值时所发生的情

如果为索引指定了IGNORE_DUP _KEY,并且执行了创建重复键的

INSERT语句,SQL Server将发出警告消息并忽略重复的行

DROP_EXISTING

指定应除去并重建已命名的先前存在的聚集索引或非聚集索引。指定索引名必须与现有的索引名相同

STATISTICS_NORECOME

指定过期的索引统计不会自动重新计算

SORT_IN_TEMPDB

指定用于生成索引的中间排序结果将存储在tempdb数据库中

请看下面的IGNORE DUP KEY选项应用实例:

CREATE UNIQUE CLUSTERED INDEX au_Id_Card

ON Employee(Id_Card0

WITH IGNLRE_DUP_KEY

7.3.2删除索引语句DROP  INDEX

DROP INDEX语句的功能是从数据库中删除指定的索引。DROP  INDEX语句不适用于通过定义PRIMARY KEY或UNIQUE约束创建的索引。

DROP  INDEX语句的语法结构如下:

DROP  INDEX ‘table.index|view.index’[,…n]

在删除索引时,必须指定索引所在的表或视图。例如,如果要删除表Employee上的索引au_wage,可以使用以下命令:

DROP INDEX Employee.au_wage

7.4视图管理语句

使用Transact-SQL语句可以创建、修改和删除视图。

 7.4.1创建建视图语句CREATE VIEW

 CREATE VIEW语句的功能是创建视图。视图实际上是一个虚拟的表,它以另一种方式来表示一个或多个表中的数据。

CREATE VIEW语句的语法结构如下:

CREATE WIEW [<database_name>.][<owner>.]view_name[(column[,…n])]

[WITH<view_attribute>[,…n]

AS

Select_statement

[WITH CHECK OPTION]

参数说明如下:

●  必需参数。使用CREATE VIEW语句的最简单格式为:

CREATE VIEW Title_View AS

SELECT Emp_ld,Emp_Name,Title FROM Employee

例如以表Employee的Emp Id、 Emp_ Name和Title列创建视图Title _View,可以使用以下命令:

● WITH<view attribute>子句。WITH<view_attribute>子句定义了视图的属性。可以使用的视图属性如表7.4所示。 

表7.4                    WITH子句支持的视图属性

属性

描述

ENCRYPTION

表示SQL Server加密包含CREATE VIEW语句文本的系统表列。使用

WITH ENCRYPTION可防止将视图作为SQL Server复制的一部分发布

SCHEMABINDING

将视图绑定到架构上指定SCHEMABINDING时select_statement必须包

含所引用的表、视图或用户定义函数的两部分名称(owner.object)

VIEW METADATA

指定为引用视图的查询请求浏览模式的元数据时,SQL Server将向DBLIB、ODBC和OLE DB API返回有关视图的元数据信息,而不是返回基表或表

在上面的示例中使用WITH ENCRYPTION,代码如下:

CREATE VIEW Title_View

WITH ENCRYPTION

AS

SECECT Emp_Id,Emp_Name,Title FROM Employee

● WITH CHECK OPTION。WITH CHECK OPTION选项强制视图上执行的所有数据修改语句都必须符合由select_statement设置的准则。通过视图修改行时,WITH CHECKOPTION可确保提交修改后,仍可通过视图看到修改的数据。

例如建立视图显示所有职务Title列为’部门经理’的记录,代码如下:

CREATE VIEW Title_View1

AS

SELECT Emp_Id,Emp_Name,Title FROM Employee WHERE Title=‘部门经理’

WITH CHECK OPTION

在对视图中数据进行修改时,不能改变Title列的值,否则将不能满足SELECT语句的条件。

7.4.2修改视图语句ALTER VIEW

ALTER VIEW语句的功能是更改一个先前创建的视图。

ALTER VIEW语句的语法结构如下:

ALTER VIEW[<database_name>,][<owner>,]view_name[(column[,…n])]

[WITH<view_attribute>[,…n]]

AS

[WITH CHECK OPTION]

不难发现,ALTER TABLE语句和CREATE TABLE的参数并没有差别。请读者参照CREATE VIEW中的说明。

例如将上面视图Title Viewl中的筛选条件变为Title=‘职员’,请使用以下语句:

ALTER VIEW Title_View1(Emp_Id,Emp_Name,Title)

AS

SELECT Emp_Id,Emp_Name,Title FROM Employee WHERE Title=‘职员’

7.4.3删除视图语句DROP VIEW

DROP VIEW语句的功能是删除一个或多个视图。

DROP VIEW语句的语法结构如下:

DROP VIEW {view},[,…n]

view是要删除的视图。

例如要删除视图Title _Viewl,可以使用以下命令:

DROP VIEW Title_View1

除去视图时,将从sysobjects、 syscolumns、 syscomments、sysdepends和sysprotects系统表中删除视图的定义及其他有关视图的信息。还将删除视图的所有权限。

 7.5数据查询语句

在Transact-SQL语言中,使用SELECT语句实现数据查询,并把查询结果以表格的形式返回。在数据库的实际应用中,SELECT语句的使用是非常频繁的。因为对于一个比较成熟的数据库系统而言,插入、修改和删除数据的工作只需要少数人员负责完成,而绝大多数的用户都是共享数据库中数据,生成各种各样需要的表格。

所以本书将使用一节的篇幅,介绍数据查询语句SELECT的各种使用方法。

7.5.1SELECT语句语法简介

我们已经知道,SELECT语句的作用是从数据库中查询满足条件的数据,并以表格的形式返回。一条简单的SELECT语句如下:

SELECT*FROM Employee

SELECT语句的功能非常强大,所以它的语法结构也比较复杂。为了使读者能够摆脱枯燥的语法,更加直观地了解SELECT语句,本书将首先介绍SELECT语句的主要使用格式。内容如下:

SECECT 子句

[INTO 子句]

FROM子句

[WHERE子句]

[GROUP BY子句]

[HAVING子句]

[ORDER BY子句]

除了以上子句,SELECT语句中经常出现的关键字还包括UNION运算符、COMPUTE子句、FOR子句和OPTION子句。

各子句的主要作用如表7.5所示。

表7.5                SELECT语句中各子句的说明

SELECT子句

描述

SELECT子句

指定由查询返回的列

INTO子句

创建新表并将结果行从查询插入新表中

FROM子句

指定从其中检索行的表

WHERE子句

指定用于限制返回的行的搜索条件

GROUP BY子句

指定查询结果的分组条件

HAVING子句

指定组或聚合的搜索条件

ORDER BY子句

指定结果集的排序

UNION运算符

将两个或更多查询的结果组合为单个结果集,该结果集包含联合查询中的所有查询的全部行

COMPUTE子句

生成合计作为附加的汇总列出现在结果集的最后。当与BY一起使用时,

COMPUTE子句在结果集内生成控制中断和分类汇总。可在同一查询内

COMPUTE BY和COMPUTE

FOR子句

FOR子句用于指定BROWSE或XML选项

OPTION子句

指定应在整个查询中使用所指定的查询提示。每个查询提示只能指定一次,但允许指定多个查询提示。用该语句只可能指定一个OPTION子句。查询提示影响语句中的所有运算符。如果主查询中涉及UNION,则只有涉及UNION运算符的最后一个查询可以有OPTION子句

以上各子句的具体使用方法,将在下面的小节中结合实例讲解。

7.5.2检验查询结果的方法

读者可以与前面一样,使用osql工具运行SELECT语句,检验查询的结果。例如在osql中运行以下命令:

USE newdb

SELECT Emp_Name FROM Employee

GO

结果为:

Emp_Name

---------------------------------

Johney Lee

Mark Wang

Sherry Zhang

John Li

Marry Ma

Fransic Zhang

Charley Liu

Cindy Lu

Richard Song

James Fan

Jack Liu

Lucy Su

(12行受到影响)

从结果可以清晰地看到Employee表中所有Emp Name列的内容。可见,osql是检验查询结果的一种简单实用的方法。

 但是由于显示模式的限制,在显示大量数据时,使用osql查看结果效果并不好。例如在osql中执行以下命令:

use  newdb

SELECT * FROM Employee

GO

结果如下:

上面的结果显然无法令人满意,因此从结果中很难出数据和列的对应关系。不过没有关系,SQL Server提供了查询分析器,可以非常方便地浏览查询结果。

在“开始”菜单中依次选择“程序”/"Microsoft SQL Server"/“查询分析器”,就可以打开“SQL查询分析器”窗口。首先看到的是“连接SQL Server”对话框,需要通过身份认证才可以进入,如图7.4所示。

图7.4进入SQL查询分析器的身份认证对话框

进入SQL查询分析器的主窗口以后,首先要选择SQL语句运行的数据库。默认情况下,数据库为master.选择“查询”菜单中的“更改数据库”命令,打开“选择数据库”对话框,选择newdb,然后单击“确定”按钮,如图7.5所示。

图7.5选择数据库

在左侧上面的空白窗口中输入以下命令:

SELECT *FROM Employee

然后单击工具栏中的执行按钮卜,查询结果就会出现在下面的网格中,如图主7石所示。

图7.6 SQL查询分析器

虽然是查询分析器,但实际上可以使用它执行任何SQL命令。例如CREATE TABLE等。单击“保存”按钮,可以将SQL命令保存为*.sql文件,以后再使用此命令时可以直接打开此文件获得。

7.5.3最基本的SELECT语句

最基本的SELECT语句只包括SELECT子句和FROM子句。下面分别对SELECT子句和FROM子句的具体内容进行介绍。

●  SELECT子句。SELECT子句是SELECT语句的关键部分。它的作用是指定由查询返回的列。

SELECT子句的语法结构如下:

SELECT [ALL|DISTINCT]

[TOP n [PERCENT ][WITH TIES]]

<select_list>

参数说明如表7.6所示。

表7.6                    SELECT子句的参数说明

参数

描述

ALL

指定在结果集中可以显示重复行。ALL是默认设置

DISTINCT

指定在结果集中只能显示唯一行。空值被认为相等。ALL和DISTINCT不能同时使用

TOP n

[PERCENT]

指定只从查询结果集中输出前n行。如果还指定了PERCENT,则只从结果集中输出前百分之n行。当指定时带PERCENT时,n必须是介于0和100之间的整数

WITH TIES

指定从基本结果集中返回附加的行,这些行包含与出现在TOP n (PERM,乃行最后ORDER BY列中的值相同的值

<select list>

为结果集选择的列。选择列表是以逗号分隔的一系列表达式。如果返回查询到的所有列,则使用*表示。关于<select list>的具体使用,将在后面部分结合实例介绍

●  FROM子句。FROM子句指定从其中检索行的表。

FROM子句的语法结构如下:

[FROM {<table_sourse>}[,…n]]

参数<table_source>指定用于SELECT语句的表、视图、派生表和联接表。在本节中,时不考虑派生表和联接表的情况。

在上一节中,读者已经认识了一个简单的SELECT语句,就是下面再把这条语句丰富起来。

●  使用DISTINCT。DISTINCT的作用是显示唯一行。例如,要显示公司所有的职务,如果使用以下命令:

USE newdb

SELECT Title FROM Employee

GO

结果为:

这个结果并不是我们需要的,原因是存在许多重复数据。如果使用DISTINCT,执行以下命令:

USE newdb

SELECT DISTINCT Title FROM Employee

GO

结果为:

这与需要的结果完全相同。

●使用TOP n [PERCENT].如果只需要显示前n行,可以在SELECT语句中使用TOP n [PERCENT]。例如:

USE newdb

SELECT TOP 3 Emp_Name FROM Employee

GO

结果为:

●改变显示的列标题。从上面的实例中可以看到,结果中的标题部分都是显示列名。对于不熟悉数据库结构的用户来说,这些列名很不容易理解。可以在<select lis户中使用AS子句,自定义显示标题。例如:

USE newdb

SELECT TOP 3 Emp_Name as 姓名,Title as 职务 FROM Employee

GO

结果为:

7.5.4设五查询条件

WHERE子句指定用于限制返回的行的搜索条件。它的语法结构如下:

[WHERE <search_condition>|<old_outer_join>]

<old_outer_join>::=

 column_name{*=|=*}column_name

参数<search condition>是通过使用谓词限制结果集内返回的行。对搜索条件中可以包含的谓词数量没有限制。

参数<old outerjoin>在WHERE子句中指定外联接。本节将不对联接进行讲解。

例如,下面语句的作用是从表Employee中查询所有年龄大于30而且小于40的行。

USE newdb

SELECT Emp_Name,Age FROM Employee WHERE Age>30 AND Age<40

GO

结果为:

Emp_Name               Age

-------------------------        ------

Johney Lee                35

Charley Liu                38

(2  行受到影响)

读者可以在WHERE子句中使用LIKE关键字和通配符。例如,要查询所有名字以字母J开头的员工姓名,可以使用以下语句:

USE newdb

SELECT Emp_Name FROM Employee WHERE Emp_Name LIKE ‘J%’

GO

结果为:

Emp_Name

-------------------------

Johney Lee

John Li

James Fan

Jack Liu

(4 行受到影响)

7.5.5时查询结果排序

ORDER BY子句可以指定结果集的排序。它的语法结构如下:

[ORDER BY {order_by_expression[ASC|DESC]} [,…n]]

参数order by_expression指定要排序的列。ASC表示按照递增的顺序排列,DESC表示按照递减的顺序排列。ASC为默认值。

例如,如果按照员工姓名排序,可以使用以下命令:

USE newdb

SELECT Emp_Name FROM Employee ORDER BY Emp_Name

GO

结果为:

Emp_Name

-------------------------

Charley Liu

Cindy Lu

Fransic Zhang

Jack Liu

James Fan

John Li

Johney Lee

Lucy Su

Mark Wang

Marry Ma

Richard Song

Sherry Zhang

(12 行受到影响)

7.5.6使用聚合函数

SELECT语句不仅可以显示表或视图中的列,还可以对列应用聚合函数,进行统计。

● COUNTO例如要查询公司的员工总数,可以使用以下命令:

USE newdb

SELECT COUNT(*) FROM Employee

GO

结果为:

------------

       12

(1 行受到影响)

● AVGO例如要查询公司员工的平均收入,可以使用以下命令:

USE newdb

SELECT AVG(Wage) FROM Employee

GO

结果为:

-------------

    3433.333333

(1行受到影响)

● SUM()例如要查询公司员工的工资总数,可以使用以下命令:

USE newdb

SELECT SUM(Wage)FROM Employee

GO

结果为:

------------------------------

             41200.00

(1行受到影响)

其他常用的聚合函数的使用情况与上面的示例相近,读者可以根据需要选择适当的聚合函数进行统计。

7.5.7对查询结果分组

GROUP BY子句指定查询结果的分组条件。

它的语法结构如下:

[GROUP BY [ALL]group_by_expression[,…n]

[WITH {CUBE|ROLLUP}]

]

如果SELECT子句<select list/中包含聚合函数,则计算每组的汇总值。

例如要查询各职位的平均工资,可以使用以下命令:

USE newdb

SELECT Title AS 职位,AVG(Wage) AS 平均工资 FROM Employee GROUP BY Title

GO

结果为:

职位                               平均公资

--------------------------------------------        ---------------------------

部门经理                            4080.000000

职员                                2633.333333

总经理                              5000.000000

(3 行受到影响)

指定GROUP BY时,选择列表中每一个非聚合表达式内的所有列都应包含在GROUP BY列表中,或者GROUP BY表达式必须与选择列表表达式完全匹配。

例如要执行以下命令:

USE newdb

SELECT Emp_Name,Title FROM Employee GROUP BY Title

GO

结果为:

消息8210,级别16,状态1,服务器NTSERVER,行2

列’Employee.Emp_name’在选择列表中无效,因为该列既不包含在聚合函数中,也不包含在GROUP BY子句中。

●  使用ALL.使用ALL关键字可以包含所有组和结果集,甚至包含那些任何行都不满足WHERE子句指定的搜索条件的组和结果集。如果指定了ALL,将对组中不满足搜索条件的汇总列返回空值。

例如要显示各部门女员工的平均工资,并按照部门编号和性别分组,可以执行以下语句:

USE newdb

SELECT Dep_Id,Sex,AVG(Wage)FROM Employee WHERE Sex =‘       女’ GROUP BY Sex,Dep_Id

GO

运行结果为:

Dep_ld   Sex

-----    ----             --------------------------------------------

2      女                2500.000000

3      女                                3500.000000

4      女                                3000.000000

6      女                                2700.000000

(4行受到影响)

如果在GROUP BY子句中使用ALL,执行以下语句:

USE newdb

SELECT Dep_Id,Sex,AVG(Wage)FROM Employee WHERE Sex=‘女’GROUP ALL Sex,Dep_Id

GO

运行结果为:

Dep_ld   Sex

-------     ---            --------------------------------------------

1        男                                      NULL

2        男                    NULL

2       女                2500.000000

3        男                                       NULL

3        女                                3500.000000

4        男                       NULL

4    女                                3000.00000

5    男                                       NULL

6    男                                       NULL

6    女                               2700.000000

警告:聚合或其他SET操作消除了空值

(10行受到影响)

虽然Sex=‘男’的行并不满足WHERE子句的要求,但是因为有ALL关键字,所以它们也出现在结果集中。只不过它们对应的聚合函数值都为NULL.

●使用WITH{CUBE}ROLLUP}。WITH CUBE和WITH ROLLUP的作用都是在结果集中按照分组列显示汇总行。CUBE和ROLLUP的不同在于,CUBE对所有分组列分别汇总,按照每个分组列生成汇总行;而ROLLUP只能第一个分组列生成汇总行。

 首先来看一个WITH CUBE的示例。

USE newdb

SELECT Dep_Id,Sex,AVG(Wage) FROM Employee GROUP BY Sex,Dep_Id WITH CUBE

GO

运行结果为:

Dep_ld     Sex

--------      -----          -----------------------------------

1          男                        5000.00000

2          男                        3650.00000

3          男                        2300.00000

4          男                        4300.00000

5          男                        3300.00000

6          男                        4000.00000

NULL   男                        3687.00000

2     女                         2500.00000

3     女                         3500.00000

4     女                         3000.00000

6     女                         2700.00000

NULL   女                         2925.00000

NULL      NULL                      3433.333333

1          NULL                      5000.00000

2           NULL                      3266.66666

3           NULL                      2900.00000

4      NULL                      3650.00000

5      NULL                      3300.00000

6      NULL                      3350.00000

(19行受到影响)

下面分析一下这个结果集的含义。

 Dep Id=NULL的列是按照Sex列统计生成的汇总行。所以可以看出,女员工的平均工资为2925.00元,而男员工的平均工资为3687.50元。

 Sex=NULL的列是按照Dep_Id列统计生成的汇总行。所以可以看出,编号为1的部门平均工资为5000.00元,编号为2的部门平均工资为3266.666666元,……。

 Dep Id=NULL并且Sex=NULL的列是总的统计汇总行。所以公司员工的平均工资为3433.333333。

 首先来看一个WITH CUBE的示例。

USE newdb

SELECT Dep_Id,Sex,AVG(Wage)FROM Employee GROUP BY Sex,Dep_Id WITH ROLLUP

GO

运行结果为:

Dep_ld      Sex

---------       ----         -----------------------------

1          男                        5000.00000

2          男                        3650.00000

3          男                        2300.00000

4          男                        4300.00000

5          男                        3300.00000

6          男                        4000.00000

NULL   男                        3687.00000

2     女                         2500.00000

3     女                         3500.00000

4     女                         3000.00000

6     女                         2700.00000

NULL   女                         2925.00000

NULL      NULL                      3433.333333

(13行受到影响)

与使用WITH CUBE参数的结果集相比,这个示例的结果集行数较少。这是因为WITHROLLUP参数只对第一个分组列Sex生成汇总行。

7.5.8指定组或聚合的搜索条件

HAVING子句的功能是指定组或聚合的搜索条件。HAVING通常与GROUP BY子句一起使用。如果不使用GROUP BY子句,HAVING的作用与WHERE子句一样。

HAVING与WHERE的区别在于:WHERE子句搜索条件在进行分组操作之前应用;而HAVING搜索条件在进行分组操作之后应用。HAVING语法与WHERE语法类似,但HAVING可以包含聚合函数。

例如如果查询平均工资大于3500.00元的部门,并显示部门编号和平均工资,可以使用以下语句:

USE newdb

SELECT Dep_Id,AVG(Wage)FROM Employee GROUP BY Dep_Id HAVING AVG(Wage)>3500

GO

运行结果为:

Dep_ld

--------               -------------------------------------

1                                   5000.000000

4                                   3650.000000

(2行受到影响)

7.5.9生成汇总行

使用COMPUTE子句可以生成合计作为附加的汇总列出现在结果集的最后。当与BY一起使用时,COMPUTE子句在结果集内生成控制中断和分类汇总。

COMPUTE子句的语法结构如下:

[COMPUTE

 {{AVG|COUNT|MAX|MIN|STDEV|STDEVP

 |VAR|VARP|SUM

(    expression)[,…n]

[BY expression[,…n]]

语句中聚合函数的功能请查阅第6章中关于函数的介绍。

BY expression参数是在结果集内生成控制中断和分类汇总。如果使用COMPUTE BY,则必须也使用ORDER BY子句。表达式必须与在ORDER BY后列出的子句相同或是其子集,并且必须按相同的序列。

例如,要查询所有员工的工资,并对工资总额进行汇总,可以使用以下命令:

USE newdb

SELECT Emp_Name,Wage FROM Employee COMPUTE SUM(Wage)

GO

运行结果为:

Emp_Name                   Wage

---------------------------------                        -----------------------

Johney Lee                                              5000

Mark Wang                                              4500

Sherry Zhang                                             2500

John Li                                                  2800

Marry Ma                                              3500

Fransic Zhang                                           2300

Charley Liu                                             4300

Cindy Lu                                               3000

Richard Song                                            4100

James Fan                                              2500

Jack Liu                                                4000

Lucy Su                                                2700

Sum

_______________________________________________

                                         41200

(13行受到影响)

工资总额为41200元。

7.5.10连接查询

在很多情况下,需要从多个表中提取数据,组合成一个结果集。如果一个查询需要对多个表进行操作,则将此查询称为连接查询。

通常可以将连接查询分为以下几种情形:

●等值连接;

●非等值连接;

●内连接;

●外连接。

下面分别通过实例对这几种方法进行介绍。

●等值连接。等值连接是非常常用的一种连接方法。有些列同时出现在不同的表中,例如在表Employee和表Department中都有Dep Id列。使用等值连接可以把两个表中相对应的记录连接在一起,得到来自两个表的数据。

例如,在前面的示例中,部门信息都是以编号的形式显示,这样对用户来说很不直观。使用等值连接就可以在显示员工信息时显示所在部门的名称,方法如下:

USE newdb

SELECT d.Dep_Name,e.Emp_Name FROM Department d,Employee WHERE d.Dep_Id=e.Dep_id

GO

运行结果为:

Dep_Name                                     Emp_Name

------------------------------  -----------               ---------------------

公司领导                      Johney Lee

办公室                     Mark Wang

办公室                     Sherry Zhang

办公室                     John Li

财务部                     Marry Ma

财务部                     Fransic Zhang

行政部                     Charley Liu

行政部                   Cindy Lu

业务部                   Richard Song

业务部                   James Fan

后勤部                                      Jack Liu

后勤部                                      Lucy Su

(12行受到影响)

●非等值连接。如果在连接条件中不使用等号,则此连接就是非等值连接。在非等值连接中,可以使用>、冲、<、。、!=等比较运算符,也可以使用BETWEEN一AND等谓词。

请看下面的非等值连接示例:

USE newdb

SELECT d.Dep_Name,e.Emp_Name FROM Department d,Eployee WHERE d.Dep_Id>e.Dep_id

GO

运行结果为:

结果将列出所有满足d.Dep_Id>e.Dep_Id的行。这个示例并没有实际意义,而在实际应用中,绝大多数情况下都是使用等值连接。

●外连接。表之间的连接可以分为等值连接和非等值连接,也可以分为内连接(InnerJoin)和外连接(Outer Join).所谓内连接,就是表中的行互相连接,结果集的行数等于每个表的满足条件的行数的乘积行数。内连接中WHERE子句从连接后的行虽筛选出符合条件的行。在内连接中,参与连接的表是平等的。

与内连接相对,参与外连接的表有主次之分。以主表的每一行数据去匹配从表中的数据列,符合连接条件的数据将直接返回到结果集中,对那些不符合连接条件的列,将被填上NULL值后再返回到结果集中。

外连接又可以分为左连接(LEFT OUTER JOIN)和右连接(RIGHT OUTER JOIN)。如果主表在左侧,则称之为左连接;反之,则称之为右连接。

例如,请看下面的外连接示例:

USE newdb

SELECT d.Dep_Name,e.Emp_Name FROM Department d LEFT JOIN Eployee e ON e.Dep_Id

GO

运行结果为:

●表到自身的连接。还可以建立表到其自身的连接,通常称这种连接为自连接。

例如,要查询年龄相同的员工,可以使用以下命令:

USE newdb

SELECT e1.Emp_Name,e1.Age FROM Employee e1

JOIN Employee e2 ON e1.Emp_Id<>e2.Emp_Id AND e1.Age=e2.Age

GO

运行结果为:

7.5.11子查询

所谓子查询就是一个SELECT语句中又嵌入了一个SELECT语句。WHERE子句和HAVING子句可以嵌套SELECT 语句。

例如,要显示财务部的所有员工,但是又不知道财务部的部门编号,可以使用以下命令:

USE newdb

SELECT Emp_Name FROM Employee WHERE Dep_Id=

(SELECT Dep_Id FROM Department WHERE Dep_Name=‘财务部’)

GO

运行结果为:

7.5.12合并查询

合并查询是将两个或更多查询的结果组合为单个结果集,该结果集包含联合查询中的所有查询的全部行。这与使用联接组合两个表中的列不同。

使用UNION运算符组合两个查询的结果集的两个基本规则是:

●所以查询中的列数和列的顺序必须相同;

●数据类型必须兼容。

例如,要查询各个部门的部门经理,可以使用以下命令:

USE newdb

SELECT Dep_Id,Dep_Name FROM Department WHERE Dep_Name<>‘公司领导’

UNION

SELECT Dep_Id,Emp_Name FROM Employee WHERE Title =‘部门经理’

GO

运行结果为:

7.5.13保存查询结果

有些读者可能需要将查询结果保存到一个新表中,以便日后查看。使用INTO子句可以创建一个新表,并用SELECT的结果集填充该表。新表的结构由选择列表中列的特性定义。

例如,将办公室的所有员工的姓名和职务信息保存到表Office中,可以使用以下命令:

USE newdb

SELECT e.Emp_Name,e.Title

INTO Office

FROM Employee e,Deparment d

WHERE e.Dep_id =d.Dep_Id.Dep_Name=‘办公室’

GO

SELECT *FROM Office

GO

运行结果为:

表明结果己经保存到新表Office中。

7.6数据更新语句

数据库的更新包括插入数据、修改数据和删除数据。这些操作对应的Transact-SQL语句如下:

●插入数据一INSERT语句:

●修改数据一UPDATE语句:

●删除数据一DELETE语句。

7.6.1插入数据语句INSERT

在建成数据库结构以后,首先要做的一项工作就是插入数据。使用INSERT语句可以实现此功能。INSERT语句的语法结构如下:

参数说明如下:

●[INTO]一个可选的关键字,可以将它用在INSERT和目标表之间。

● table name将要接收数据的表或table变量的名称。

● WITH (<table hint limited>【~川】一指定目标表所允许的一个或多个表提示。需要有WITH关键字和圆括号。不允许有READPAST . NOLOCK和READUNCOMMITTED。

●view name视图的名称及可选的别名。通过view name来引用的视图必须是可更 新的。

● rowset function limited是OPENQUERY或OPENROWSET函数。

● (column list)要在其中插入数据的一列或多列的列表。必须用圆括号将column list 括起来,并且用逗号进行分隔。

● VALUES引入要插入的数据值的列表。对于column list(如果已指定)中或者表中的每个列,都必须有一个数据值。必须用圆括号将值列表括起来。如果VALUES列表中的值与表中列的顺序不相同,或者未包含表中所有列的值,那么必须使用column list明确地指定存储每个传入值的列。

● DEFAULT强制SQL Server装载为列定义的默认值。如果对于某列并不存在默认值,并且该列允许NULL那么就插入NULL.

● Expression一个常量、变量或表达式。表达式不能包含SELECT或EXECUTE语句。

● derived table任何有效的SELECT语句,它返回将装载到表中的数据行。

● execute statement任何有效的EXECUTE语句,它使用SELECT或READTEXT 语句返回数据。

● DEFAULT VALUES强制新行包含为每个列所定义的默认值。

下面是几个INSERT语句的实用示例。

例如向表Department中插入记录,可以使用以下命令:

USE newdb

INSERT INTO Department VALUES(100,’调职人员’)

GO

SELECT *FROM Department

GO

运行结果为:

在插入员工数据时,有时只需要输入部分列的数据。这就要在VALUES子句之前添加要插入列的列表,例如:

USE newdb

INSERT INTO Employee (Emp_Id,Emp_Name,Sex,Title,Dep_Id)

VALUES (100, ‘Test’,1,’职员’,2)

GO

7.6.2修改数据语句UPDATE

可以使用UPDATE命令修改表中的现有数据。UPDATE命令的语法结构如下:

UPDATE

{table_name WITH (<table_hint_limited>[…n]

|view_name

|rowset_function_limited

}

SET

{column_name={expression|DEFAULT|NULL}

|@variable=expression

|@variable=column=expression}[,…n]

{{[FROM {<table_source>}[,…n]

[WHERE

<search_condition>]

|

[WHERE CURRENT OF

{{[GLOBAL] cursor_name}|cursor_variable_name}

]}

[OPTION(<query_hint>[,…n]

参数说明如下:

● table name需要更新的表的名称。如果该表不在当前服务器或数据库中,或不为当前用户所有,这个名称可用链接服务器、数据库和所有者名称来限定。

● WITH ( < table hint limited >[…n])指定目标表所允许的一个或多个表提示。需要有WITH关键字和圆括号。不允许有READPAST , NOLOCK和READUNCOMMITTED 。

●view_name要更新的视图的名称。通过view name来引用的视图必须是可更新的。 用UPDATE语句进行的修改,至多只能影响视图的FROM子句所引用的基表中的一个。

● rowsetJunction limited OPENQUERY或OPENROWSET函数,视提供程序功能而 定。

● SET指定要更新的列或变量名称的列表。

● column name含有要更改数据的列的名称。column name必须驻留于UPDATE子 句中所指定的表或视图中。标识列不能进行更新。

● expression变量、字面值、表达式或加上括弧的返回单个值的subSELECT语句。

expression返回的值将替换column name或*variable中的现有值。

● DEFAULT指定使用对列定义的默认值替换列中的现有值。如果该列没有默认值并且定义为允许空值,这也可用来将列更改为NULL.

● @variable已声明的变量,该变量将设置为expression所返回的值。

● FROM<table source>指定用表来为更新操作提供准则。

● WHERE指定条件来限定所更新的行。

● <searcbsecondition>为要更新行指定需满足的条件。搜索条件也可以是联接所基于的条件。对搜索条件中可以包含的谓词数量没有限制。

● CURRENT OF指定更新在指定游标的当前位置进行。

● GLOBAL指定cursor name指的是全局游标。

● cursor name要从中进行提取的开放游标的名称。如果同时存在名为cursor name

 的全局游标和局部游标,则在指定了GLOBAL时,cursor name指的是全局游标。

 如果未指定GLOBAL,则cursor name指局部游标。游标必须允许更新。

●cursor-variable-name游标变量的名称。cursor variable name必须引用允许更新的

 游标。

●OPTION(< query hint >[,..n ]=指定优化程序提示用于自定义SQL Server的语句处理。

<query hint>包括以下选项:

口{HASH}ORDER}GROUP指定在查询的GROUP BY或COMPUTE子句中指

 定的聚合使用哈希或排列。

口{LOOPIMERGE}HASH 1} JOIN指定在整个查询中所有的联接操作由循环联接、

 合并联接或哈希联接来完成。如果指定了不止一个联接提示,则查询优化器为允许的联接选择开销最少的联接策略。如果在同一个查询中也为特定表对指定了联接提示,则该提示在两表的联接中优先。

口{MERGEIHASHICONCAT}UNION指定所有的UNION操作通过合并、哈希或

 串联UNION集合来完成。如果指定了不止一个UNION提示,查询优化器就会从

 这些指定的提示中选择开销最少的策略。

口FAST number rows指定对查询进行优化,以便快速检索第一个number rows(非

 负整数)。在第一个number rows返回后,查询继续进行并生成完整的结果集。

口FORCE ORDER指定查询语法所指示的联接顺序在查询优化过程中予以保留。

口MAXDOP number只对指定了sp configure的~degree of parallelism配置选项的

 查询替代该选项。当使用MAXDOP查询提示时,所有和~degree of parallelism配

 置选项一起使用的语义规则均适用。

口ROBUSTPLAN强制查询优化器尝试执行一个计划,该计划以性能为代价获得最大

 可能的行大小。如果没有可行的计划,则查询优化器返回错误,而不是将错误检测延迟至查询执行。行可能包含长度可变的列;SQL Server允许定义最大可能大小超出SQL Server处理能力的行。通常,应用程序存储实际大小在SQL Server处理能力范围内的行,而不管最大可能大小。如果SQL Server遇到过长的行,则返回执行错误。

口KEEP PLAN强制查询优化器对查询放宽估计的重新编译闽值。当对表中索引列的

 更改(更新、删除或插入)达到估计数目时查询会自动重新编译,该估计数目即为重新编译闽值*指定KEEP PLAN将确保当表有多个更新时不会频繁地对查询进行重

 新编译。.

请看以下示例程序,它的功能是将所有员工的工资上涨10%.

USE newdb

UPDATE Employee SET Wage=Wage*1.1

GO

运行结果为:

(13行受到影响)

可以通过WHERE子句限定修改数据的条件,例如:

USE newdb

UPDATE Employee SET Wage =Wage*1.1 WHERE Title=‘部门经理’

GO

运行结果为:

(5行受到影响)

7.6.3删除数据语句DELETE

可以使用DELETE命令删除表中的现有数据。DELETE命令的语法结构如下:

DELECT

[FROM

{table_name WITH (<table_hint_limited>[…n])

|view_name

|rowset_function_limited

}

[FROM {<table_sourse>}[,…n]]

[WHERE

{<search_condition>

 |{[CURRENT OF

{{[GLOBAL]cursor_name}

|cursor_variable_name

}

]}

}

]

[OPTION(query_hint>[,…n])]

参数说明与UPDATE语句的参数相同

如果要删除表Employee中姓名为Test的员工,可以使用以下命令:

USE newdb

DELECT FROM Employee WHERE Emp_Name=‘Test’

GO

运行结果为:

(1行受到影响)

第8章 存储过程及触发器管理

8.1存储过程管理

8.2触发器管理

第9章 游标管理

10并发控制与事务 

11安全管理 

11.1登录帐户

11.1.1  添加登录帐户

    2.使用Transact-SQL语句添加登录帐户

    可以使用CREATE LOGIN语句添加登录帐户。

    CREATE LOGIN login_name { WITH <option_list1> | FROM <sources> }

    <sources> ::=    WINDOWS [ WITH <windows_options> [ ,... ] ]

    <option_list1> ::= PASSWORD = 'password' [ HASHED ] [ MUST_CHANGE ] [ , <option_list2> [ ,... ] ]

    <option_list2> ::= DEFAULT_DATABASE = database | DEFAULT_LANGUAGE = language | CHECK_EXPIRATION = { ON | OFF} | CHECK_POLICY = { ON | OFF}

    <windows_options> ::=DEFAULT_DATABASE = database|DEFAULT_LANGUAGE = language

其中的参数说明如下:

login_name:指定创建的登录名。

WINDOWS:指定将登录名映射到 Windows 登录名。

PASSWORD = 'password':仅适用于 SQL Server 登录名。指定正在创建的登录名的密码。

HASHED:仅适用于 SQL Server 登录名。指定在 PASSWORD 参数后输入的密码已经过哈希运算。

MUST_CHANGE:仅适用于 SQL Server 登录名。SQL Server 将在首次使用新登录名时提示用户输入新密码。

DEFAULT_DATABASE = database:指定将指派给登录名的默认数据库。如果未包括此选项,则默认数据库将设置为 master。

DEFAULT_LANGUAGE = language:指定将指派给登录名的默认语言。

CHECK_EXPIRATION = { ON | OFF }:仅适用于 SQL Server 登录名。指定是否对此登录帐户强制实施密码过期策略。

CHECK_POLICY = { ON | OFF }:仅适用于 SQL Server 登录名。指定应对此登录名强制实施运行 SQL Server 的计算机的 Windows 密码策略。

注意:

密码是区分大小写的。

只有创建SQL Server登录名时,才支持对密码预先进行哈希运算。

如果指定MUST_CHANGE,则CHECK_EXPIRATION和CHECK_POLICY必须设置为ON。否则,该语句将失败。

不支持CHECK_POLICY=OFF和CHECK_EXPIRATION=ON的组合。

如果CHECK_POLICY设置为OFF,将对lockout_time进行重置,并将CHECK_EXPIRATION设置为OFF。

只有在Windows Server 2003及更高版本上才会强制执行CHECK_EXPIRATION和CHECK_POLICY。

例11-2-1:创建一个 SQL Server 登录帐户USER1,密码为Abc123#$。

11.1.2  删除登录帐户

2.使用Transact-SQL语句删除登录帐户

可以使用DROP LOGIN删除登录帐户,语法形式如下:

DROP LOGIN login_name

其中login_name是要删除的登录名。

例11-2-2:删除SQL Server帐户USER1。

数据库用户

2.使用Transact-SQL语句添加数据库用户

可以使用CREATE USER添加数据库用户,其基本语法形式如下:

CREATE USER user_name     [ {  FOR | FROM }{ LOGIN login_name }| WITHOUT LOGIN  ]

  [ WITH DEFAULT_SCHEMA = schema_name ]

其中的参数说明如下:

user_name:指定在此数据库中用于识别该用户的名称。user_name的长度最多是128个字符。

LOGIN login_name:指定要创建数据库用户的SQL Server登录名。login_name必须是服务器中有效的登录名。

WITH DEFAULT_SCHEMA = schema_name:指定服务器为此数据库用户解析对象名时将搜索的第一个架构。

WITHOUT LOGIN:指定不应将用户映射到现有登录名。

注意:

如果已忽略FOR LOGIN,则新的数据库用户将被映射到同名的SQL Server登录名。

如果未定义DEFAULT_SCHEMA,则数据库用户将使用dbo作为默认架构。

如果用户是sysadmin固定服务器角色的成员,则忽略DEFAULT_SCHEMA的值。

映射到SQL Server登录名不能包含反斜杠字符(\)。

例11-3-1:在STUDENT数据库中为SQL Server用户USER1添加数据库用户,并取名为USER1,默认架构为STU。

11.3.2  删除数据库用户

利用Transact-SQL语句同样可以删除数据库用户,其语法形式如下:

DROP USER user_name

其中的参数user_name指定在此数据库中用于识别该用户的名称。

例11-3-2:从STUDENT数据库中删除数据库用户USER1。

11.4.2  使用Transact-SQL 语句管理权限

在Transact-SQL语言中,使用GRANT、DENY和REVOKE三种命令来管理权限。

GRANT命令用于把指定的权限授予某一用户。

GRANT { ALL [ PRIVILEGES ] }| 权限名 [ ( 列名 [ ,...n ] ) ] [ ,...n ]

      ON 数据库对象名 TO 用户/角色 [ WITH GRANT OPTION ]

说明:GRANT OPTION选项指示被授权者在获得指定权限的同时还可以将指定权限授予其他用户或角色。

DENY命令用来禁止用户使用指定的权限。

DENY { ALL [ PRIVILEGES ] }| 权限名 [ ( 列名 [ ,...n ] ) ] [ ,...n ]

      [ ON 数据库对象名 TO 用户/角色  [ CASCADE]

说明:CASCADE选项指示拒绝授予指定用户该权限,同时,对该用户授予了该权限的所有其他用户,也拒绝授予该权限。如果授权时使用了WITH GRANT OPTION 选项,则此处为必选项。

REVOKE命令用来收回用户所拥有的某些权限,使其不能执行此操作,除非该用户被加入到某个角色中,从而通过角色获得授权。

REVOKE [ GRANT OPTION FOR ]{ [ ALL [ PRIVILEGES ] ]| 权限名 [ ( 列名 [ ,...n ] ) ] [ ,...n ]}[ ON 数据库对象名] { TO | FROM } 用户/角色 [ CASCADE]

说明:CASCADE选项指示当前正在撤消的权限也将从其他被该用户授权的其他用户中撤消。使用CASCADE参数时,还必须同时指定GRANT OPTION FOR参数。

例11-4-2:将对数据库STUDENT中T_SCORE表的SELECT权限授予数据库用户USER2。

例11-4-3:拒绝USER2对T_COURSE表中的C_NUMBER列的SELECT权限。

例11-4-4:收回USER2对T_SCORE表的SELECT权限。

例11-4-5:将在STUDENT数据库中创建数据表的权限授予用户USER2。

posted on 2011-06-07 09:53  敌敌  阅读(16161)  评论(1编辑  收藏  举报