从零开始学SQL Server
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

第2篇 SQL Server基础篇

第3章 管理SQL Server 2005的工具——SQL语言

经过前面两章的学习,我们已经对SQL Server 2005数据库管理系统有了一个大致的概念,从这一章开始我们将对该数据库管理系统的具体内容展开全面的介绍,让读者通过自己的努力去揭开SQL Server 2005的神秘面纱,本章将从SQL语言讲起,让读者对SQL语言的基本语法先有一个大致的了解,为以后的学习打下一个基础。本章的主要内容如下:

❑ SQL语言简介。

❑ SQL语言中的数据类型。

❑ SQL语言中的变量。

❑ SQL语言中的运算符。

❑ SQL语言中的表达式。

3.1 SQL语言简介

SQL是Structured Query Language(机构化查询语言)的简写,是高级的非过程化编程语言,允许用户在高层数据结构上工作。它不要求用户指定对数据的存放方法,也不需要用户了解具体的数据存放方式,所以具有完全不同底层结构的、不同数据库系统可以使用相同的SQL语言作为数据输入与管理的接口。最早是IBM的圣约瑟研究实验室为其关系数据库管理系统SYSTEM R开发的一种查询语言,它的前身是SQUARE语言。SQL语言结构简洁,功能强大,简单易学,所以自从IBM公司1981年推出以来,SQL语言得到了广泛的应用。如今无论是Oracle、Sybase、Informix、SQL Server这些大型的数据库管理系统,还是Visual FoxPro、PowerBuilder这些在PC上常用的数据库开发系统,都支持SQL语言作为查询语言。

3.1.1 SQL语言的主要特点

SQL是一种面向数据库的通用数据处理语言规范,它具有非常强大的功能,主要包括以下几类:

❑ 提取查询数据。

❑ 插入、修改、删除数据。

❑ 生成、修改、删除数据库对象。

❑ 数据库安全控制。

❑ 数据库完整性及数据保护控制。

SQL语言的这些强大功能充分体现了关系数据语言的特点和优点。其主要的特点如下:

1.综合统一

SQL语言集数据定义语言DDL、数据操纵语言DML、数据控制语言DCL的功能于一体,语言风格统一,可以独立完成数据库生命周期中的全部活动,包括定义关系模式、录入数据以建立数据库、查询、更新、维护、数据库重构、数据库安全性控制等一系列操作要求,这就为数据库应用系统开发提供了良好的环境。例如,用户在数据库投入运行后,还可根据需要随时地、逐步地修改模式,并不影响数据库的运行,从而使系统具有良好的可扩充性。

2.高度非过程化

非关系数据模型的数据操纵语言是面向过程的语言,用它完成某项请求,必须指定存取路径。而用SQL语言进行数据操作,用户只需提出“做什么”,而不必指明“怎么做”,因此用户无须了解存取路径,存取路径的选择及SQL语句的操作过程由系统自动完成。这不但大大减轻了用户负担,而且有利于提高数据独立性。

3.面向集合的操作方式

SQL语言采用的是面向集合的操作方式,不仅查找结果可以是元组的集合,而且一次插入、删除、更新操作的对象也可以是元组的集合。

非关系数据模型采用的是面向记录的操作方式,任何一个操作其对象都是一条记录。例如,查询所有平均成绩在80分以上的学生姓名,用户必须说明完成该请求的具体处理过程,即如何用循环结构按照某条路径一条一条地把满足条件的学生记录读出来。

4.以同一种语法结构提供两种使用方式

SQL语言既是自含式语言,又是嵌入式语言。

作为自含式语言,它能够独立地用于联机交互的使用方式,用户可以在终端键盘上直接输入SQL命令对数据库进行操作。作为嵌入式语言,SQL语句能够嵌入到高级语言(如C、PB)程序中,供程序员设计程序时使用。而在两种不同的使用方式下,SQL语言的语法结构基本上是一致的。这种以统一的语法结构提供两种不同的使用方式的做法,为用户提供了极大的灵活性与方便性。

5.语言简洁,易学易用

SQL语言非常简洁。虽然SQL语言功能很强,但它只有为数不多的几条指令,另外SQL语言也非常简单,它很接近英语自然语言,因此容易学习、掌握。

正是由于SQL语言的这些优点,它才能被广泛使用,目前所有的关系型数据管理系统都支持某些形式的SQL语言,它使全部用户,包括应用程序员、数据库管理员和终端用户。

3.1.2 如何分类SQL语言

在上一节中我们提到了SQL语言具有强大的功能,这些功能可以归纳为数据查询、数据定义、数据操纵及数据控制,而我们给SQL语言分类也是从SQL语言所起的作用的角度进行的,所以我们可以将SQL语言分为以下几类。

1.数据查询语言(DQL,Data Query Language)

数据查询语言是在SQL语言中,负责进行数据查询而不会对数据本身进行修改的语句,这是最基本的SQL语句。

DQL的主要功能是查询数据,本身内核指令为SELECT,为了进行精细的查询,加入了各类辅助指令,其主条目包含SELECT、FROM、WHERE、GROUP BY和ORDER BY。

SELECT是查询的指令,其语法结构为:

        SELECT [要提取的字段,或是用 "*" 代表全部的字段]
        FROM   [要提取的数据来源对象,包含数据表、检视表与表格型使用者函数等]
        WHERE  [提取的过滤条件]
        GROUP BY [要进行汇总的群组字段]
        HAVING [要作为条件的汇总字段]
        ORDER BY [要排序的字段与方向]

2.数据定义语言(DDL,Data Definition Language)

数据定义语言是在SQL语言集中,负责数据结构定义与数据库对象定义的语言,由CREATE、ALTER与DROP 3个语法所组成,最早是由CODASYL (Conference on Data Systems Languages)数据模型开始,现在被纳入SQL指令中作为其中一个子集。

❑ CREATE:是负责数据库对象的建立,主要包括数据库、数据表、数据库索引、预存程序、用户函数、触发程序或是用户自定型别等对象,都可以使用CREATE指令来建立,而为了各式数据库对象的不同,CREATE也有很多的参数。

❑ ALTER:是负责数据库对象修改的指令,相较于CREATE需要定义完整的数据对象参数,ALTER则可依照要修改的幅度来决定使用的参数,因此在使用上并不会太困难。

❑ DROP:是删除数据库对象的指令,并且只需要指定要删除的数据库对象名称即可,在DDL语法中算是最简单的。

3.数据操纵语言(DML,Data Manipulation Language)

数据操纵语言是在SQL语言中,负责对数据库对象运行数据访问工作的指令集,以INSERT、UPDATE、DELETE 3种指令为内核,分别代表插入、更新与删除,是开发以数据为中心的应用程序必定会使用到的指令。

❑ DML主要功能即是访问数据,因此其语法都是以读取与写入数据库为主,除了INSERT以外,其他指令都可能要搭配WHERE指令来过滤数据范围,或是不加WHERE指令来访问全部的数据。

❑ INSERT是将数据插入到数据库对象中的指令,可以插入数据的数据库对象有数据表、可更新查看表两种。

❑ UPDATE指令是依给定条件,将符合条件的数据表中的数据更新为新的数值。

❑ DELETE指令为从数据库对象中删除数据的指令。

4.数据控制语言(DCL,Data Control Language)

数据控制语言在SQL语言中,是一种可对数据访问权进行控制的指令,它可以控制特定用户账户对数据表、查看表、预存程序、用户自定义函数等数据库对象的控制权。由GRANT和REVOKE两个指令组成。

这两个指令的语法结构大致是:

        GRANT [权限] ON [要授予权限的数据库对象] TO [使用者账户名称] WITH [授权选项]
        DENY [权限] ON [要授予权限的数据库对象] TO [使用者账户名称]

通过上面的介绍我们可以简单地了解SQL语言的简单分类,虽然在文中可能出现了很多让初学者理解起来有些困难的词汇,但是随着我们学习的深入,初学者就能够更加深刻地理解这些词汇的含义。

3.1.3 SQL语法简介

其实SQL命令并不是非常多,如果要把SQL用到出神入化,则只需要短短几个命令就够了,因为SQL命令是针对关系型数据库所建立的语法叙述,所以SQL在这类数据库中所发挥的功能非常的强。下面将对SQL语法基本命令进行简单的介绍,在后面的学习中我们将详细地介绍SQL语法中涉及的内容。大致上SQL语法所使用到的类型,基本上可以概括为以下几类:

❑ 类属性(Predicates):在SQL命令中用来指明要选择记录的方式。如ALL、TOP、DISTINCT等。

❑ 声明(Declaration):针对SQL Parameter或Parameter Query的名称与数据类型做声明,如PARAMETERS的声明等。

❑ 条件字句(Clause):在SQL的查询中,利用一些表达式定义查询的条件,以缩小寻找的范围,如WHERE。

❑ 运算符(Operator)与操作数(Operation):在SQL的查询中,与Operation共同组成表达式(Expression),如BETWEEN…AND运算符与INNER JOIN操作数。

❑ 函数(Function):一些常见的函数,如AVG()是求算数平均数的函数。

❑ SQL语句(Statement):SQL的语句,可以说是SQL语法的主体,用来对某一个特定的数据库发出指示,并返回相关的数据,而SQL的语法结构,基本上可以利用下面的式子来表示:命令+条件子句。例如,SELECT*FROM TAB WHERE TAB.NAME='A'。

3.1.4 如何给标识符起名

计算机语言发展至今,标识符命名逐渐摆脱了早期不区分大小写的书写样式,以及微软借Windows平台推荐和推广的匈牙利命名法(Hungarian Notation),形成目前主流的命名规则,包括以下4种样式:完全大写、完全小写、Pascal大小写和Camel大小写。所谓Pascal大小写即组成标识符的每个单词的首字母大写,其余字母小写的书写约定;而Camel大小写与Pascal大小写相似,区别仅在于其标识符的首字母恒为小写。此外,作为上述规则的补充约定,对于双字母的缩写单词,Pascal大小写要求它们全部大写,而Camel大小写则要求它们出现在标识符首部时全部小写,否则全部大写。需要强调的是,这条规则仅适用于缩写的双字母单词,如“To”、“Is”、“As”这样原生的双字母单词。

为了提供完善的数据库管理机制,SQL Server设计了严格的命名规则。在创建或引用数据库实体,如表、索引、约束等时,必须遵守SQL Server的命名规则,否则有可能发生一些难以预料和检查的错误。

1.标识符分类

SQL Server的所有对象,包括服务器、数据库及数据库对象,如表、视图、列、索引、触发器、存储过程、规则、默认值和约束等都可以有一个标识符。对绝大多数对象来说,标识符是必不可少的,但对某些对象(如约束)来说,是否规定标识符是可选择的。对象的标识符一般在创建对象时定义,作为引用对象的工具使用。

SQL Server一共定义了两种类型的标识符:规则标识符(Regular identifier)和界定标识符(Delimited identifier)。

2.规则标识符

规则标识符严格遵守标识符有关格式的规定,所以在Transact_SQL中凡是规则运算符都不必使用界定符。对于不符合标识符格式的标识符要使用界定符[]或‘’。

3.界定标识符

界定标识符是那些使用了如[]和‘’等界定符号来进行位置限定的标识符,使用界定标识符,既可以遵守标识符命名规则,也可以不遵守标识符命名规则。

4.标识符格式

❑ 标识符的首字母必须是以下两种情况之一:

第一种情况是,所有在统一码(Unicode)2.0标准规定的字符,包括26个英文字母a~z和A~Z,以及其他一些语言字符,如汉字。例如,可以给一个表格命名为“学生基本情况”。

第二种情况是, “ ”、“@”或“#”。

❑ 标识符首字母后的字符可以是下面3种情况:

第一种情况是,所有在统一码(Unicode)2.0标准规定的字符,包括26个英文字母a~z和A~Z,以及其他一些语言字符,如汉字。

第二种情况是, “ ”、“@”、“$”或“#”。

第三种情况是,0,1,2,3,4,5,6,7,8,9。

❑标识符不允许是T-SQL的保留字:由于T-SQL不区分大小写,所以无论是保留字的大写还是小写都不允许使用。T-SQL的保留字如表3.1所示。

表3.1 T-SQL保留字

(续表)

❑ 标识符内部不允许有空格或特殊字符:最后还要说明的是,以某些特殊符号开头的标识符在SQL Server系统中具有特定的含义。如“@”开头的标识符表示这是一个局部变量或是一个函数的参数;以“#”开头的标识符表示这是一个临时表或存储过程;一个以“##”开头的标识符表示这是一个全局的临时数据库对象。T-SQL的全局变量以标识符“@@”开头。为避免同这些全局变量混淆,建议不要使用“@@”作为标识符的开始。

无论是界定标识符还是规则标识符都最多只能容纳128个字符,对于本地的临时表最多可以有116个字符。

5.对象命名规则

SQL Server数据库管理系统中的数据库对象名由1~128个字符组成,不区分大小写。在一个数据库中创建了一个数据库对象后,数据库对象的全名应该由服务器名、数据库名、拥有者名和对象名这4个部分组成,格式如下:

        [[[server.][database].][owner_name].]object_name

命名必须都要符合标识符的规定。在实际引用对象时,可以省略其中某部分的名称,只留下空白的位置。

6.实例的命名习惯

在SQL Server数据库管理系统中默认实例的名字采用计算机名,实例的名字一般由计算机名和实例名两部分组成。

总之,正确掌握数据库的命名和引用方式是用好SQL Server数据库管理系统的前提,也有助于用户理解SQL Server数据库管理系统中的其他内容。

3.2 数据类型大家族

任何一种高级语言都有数据类型的概念,SQL语言也不例外,在数据结构中数据类型的定义为一个值的集合及定义在这个值集上的一组操作。下面我们将对SQL语言的数据类型进行详细的介绍,读者在学习的时候可以和学过的其他高级语言中的数据类型进行比较学习。

3.2.1 SQL Server数据类型概述

在本节中我们可能会遇到一些以前没有接触到的概念,如表的创建,对于这些我们现在不用太关心,我们只要能够理解什么时候需要用到数据类型,以及怎样使用数据类型就可以了,至于具体的操作流程会在后面的章节中进行具体的介绍。

在计算机中数据有两种特征,即类型和长度。所谓数据类型就是以数据的表现方式和存储方式来划分的数据种类。在SQL Server中每个变量、参数、表达式都有数据类型。

我们在对数据库进行一些定义操作时需要指定数据类型,如定义表列就是一个典型的操作。Transact-SQL可以定义几种数据类型,包括字符型、数字型和比特型的数据类型,在SQL Server的操作中需要用到数据类型的地方还有很多,例如,我们在定义存储过程和表的时候都会用到。

使用文本和图像数据类型定义2K字节以上的列并可以存储多余2000000字节的数据。

我们在创建表时使用的度量单位称为一个区域(extent)。当创建一个新表时,为表最初分配的空间设置为一个区域,它包括8个数据页,每个数据页的尺寸为2K字节,当表填满类分配的区域后,会为表自动分配另外的存储空间。

使用系统存储过程或使用SQL企业管理器可以得到关于分配给某个表的存储空间报告。

数据类型是在定义表列时需要考虑的第一个特性,表列的数据类型控制着可以存储在表列中的信息类型。一旦定义了表列的数据类型,它就作为表列的一个永久性特征存储起来而不能改变了。

还可以使用数据类型定义其他的数据存储结构,如参数和本地变量,参数和本地变量结构的数据存储在RAM中而不是在磁盘上,可以用于定义参数和本地变量的数据类型是数据类型的一个子集。

SQL Server还能够自动限制每个数据类型的值的范围。例如,我们在一个表列中定义了一个列的数据类型为int类型,但是我们在插入数据时插入的数据在smallint和tinyint范围之内,SQL Server会自动将我们的类型转化为smallint或者是tinyint,这样使用tinyint或smallint数据类型存储数据只需要int数据类型1/4或1/2的存储空间,这对于使用作为标志、状态指示等类型的数据非常有用。

SQL Server数据库管理系统将数据类型大致分为了两类,一类是系统默认的数据类型,另一类是用户自定义数据类型。下面将对这两类数据类型进行详细的阐述。

3.2.2 系统数据类型

SQL Server中的数据类型大致分为以下7种类型:整数数据类型、浮点数据类型、二进制数据类型、逻辑数据类型、字符数据类型、文本和图像数据类型、日期和时间数据类型。下面我们对这几种数据类型进行逐一介绍,以便读者对SQL Server数据类型有一个充分的认识。

1.整数数据类型

整数数据类型可以存储整个数字,你可以在整数上直接操作算术运算符,而不是使用函数转换,存储在整数数据类型中的数据占据的存储空间一样,而不管其具体的数字位数是多少。

数据类型的名字,如integer,是大小写敏感的。整数数据类型主要分为以下几类:

❑ int数据类型:数据类型int或integer int(或integer)可以存储在-(2E31)~2E31范围内的任意整数。以int数据类型存储的数据每一个占据4个字节的空间,使用31位存储数字的绝对值,使用一位存储正负号。

❑ smallint数据类型:存储-32768~32767之间的整数。存储在smallint数据类型中的值占据2个字节其中15位存储绝对值,使用一位存储正负号。

❑ tinyint数据类型:只能存储0~255之间的整数,每个数据占据1个字节。

2.浮点数据类型

浮点数据类型是另一组数据类型,他不像整数型的数据类型,浮点数据类型可以存储小数。

不幸的是,浮点数据类型要受到舍入误差的限制,舍入误差的浮点数据类型的精确度受指定的数据位数的影响。例如,如果指定数据类型位数是15位,则位数大于15的数据可以存储,但是大于15的数位就不能精确地表达出来,还有因为误差的存在计算返回的结果可能也不准确,舍入误差会影响数的最低位。在浮点数据类型允许的位数范围内,你可以精确存储数据。

像浮点数据类型这样的近似数值型的数据类型,因为存储在其中的值只能在某个精度范围内准确,要避免比较存储在近似数值型的数据类型中的数据,因为原有的大于精度范围位数的数据会经过舍入后进行处理。

浮点数据类型大致可以分为以下几类:

❑ real数据类型:是浮点数据类型的一种,它存储数据在4个字节中,在这个数据类型中可以存储正数和负数,可以达到7个数字的精度,这个数据类型的值的范围在3.4E-38~3.4E+38之间。

❑ float[(n)]数据类型:如果忽略参数n,需要8个字节的存储空间,可以在其中存储多达15个数字的正负数,其值的参数在1.7E-308~1.7E+308之间。

❑ 如果指定n值为1到7,则实际上是定义了一个real数据类型。如果指定n值在8~15之间,则这个数据类型的特性和忽略参数n是一样。

❑ decimal[(p[,s])]和numeric[(p[,s])]数据类型:这两个数据类型不像float或real数据类型,它们允许按指定的值精确分配给数据存储空间,值的位数和精度由给定的参数指定,可以使用2~17个字节的存储空间存储-10~10之间的值。使用p定义小数点左右两边的位数和,而使用s定义小数点右边的小数位数,s总小于等于p,如果忽略p,则指定为18;s的默认值为0。表3.2所示为分配给指定精度的字节数。

表3.2 分配给指定精度的字节数

3.二进制数据类型

❑ binary(n)数据类型:可以使用binary数据类型存储由多达255个字节组成的bit形式的数据。使用在括号中的整数指定数据的长度,从1~255。binary列中的尺寸至少为1个字节,但你可以将这些字节存为0。在输入第一个binary值时,你必须在他前面带0x。你可以使用字符0~9和A~F输入binary数据,如输入0xA0代表A0。如果输入的值大于定义的长度,则会将长出的部分截断。

❑ varbinary(n)数据类型:可以使用varbinary数据类型存储由多达255个字节组成的bit形式的数据。使用在括号中的整数指定数据的长度,从1~255。varbinary列中的尺寸至少为1个字节,但你可以将这些字节都存为0。

与binary数据类型不同的是,varbinary数据类型的存储限制为实际值使用相同的存储空间。就像binary数据类型,你必须在第一个输入的值前加上0x。你可以使用字符从0~9和A~F输入varbinary数据,如果输入的值大于定义的长度,则会将长出的部分截断。

4.逻辑数据类型

在SQL Server中逻辑数据类型只有一种,那就是bit数据类型,我们可以使用bit数据类型代表两个状态的数据信息。一个bit数据类型的数据存储在一个位中,这时只有两个可能的状态——0或1。如果输入的值不是0或1,则当做1存储。不能定义bit数据类型允许为null值。

我们还可以使用单个字节定义多达8个不同的bit表列。分配给一个或多个bit的存储空间是单个字节且bit表列不必是连续的。如果你定义了9个使用bit数据类型的表列,则需要2个字节存储所有bit型数据。值的注意的是,我们不能在使用bit数据类型的表列上定义一个索引。

5.货币数据类型

❑ money数据类型:存储货币值,存储在money数据类型中的数据值分为两部分存储,一个是整数部分,一个是小数部分,这两部分都是4个字节的整数,存储在money数据类型中的值的范围在-922337203685477.5808~922337203685477.5807之间。

❑ smallmoney数据类型:存储的货币值的范围比money数据类型小得多,其范围在-214748.3648~214748.3647之间。这个数据类型的整数部分和小数部分存储在4个字节中,所以,如果使用smallmoney而不是money,就可以节约一半的存储空间。

当向表列中插入smallmoney或money数据类型的值时,必须在数据前加上美元符号($)或其他定义货币符号,如人民币符号(¥)。

6.字符数据类型

字符数据类型可以存储包括数字在内的许多符号,字符数据类型可以存储字母、数字和特殊符号,如”[“,”]”号等。当向表列等存储结构输入数据时,可以使用单引号或双引号输入字符数据。

字符数据类型大致分为以下几类。

❑ char数据类型:这个数据类型中的每个字符都使用一个字节的存储空间。括号中的数字指定整个字符串的长度,如果输入字符长度小于15个字节,则用空格补足。一个char(n)数据类型的数据最多可用255个字符。如果某表列定义char且允许null值,则它作为varchar数据类型的表列对待。

❑ varchar数据类型:这个数据类型存储一个可变长度的字符串,最多可达255个字节,不像char数据类型,这个数据类型的存储空间可以根据实际需要变化。

例如我们定义一个表列为varchar(15),则最大可以存储的字符串长度为15,而如果不足15个字节,则不会分配额外的空间给这个数据,所以,可以使用varchar数据类型节约存储空间。

在使用char或varchar数据类型时,都会制定要输入数据的最大长度。SQL Server会自动截断长于最大长度的字符,但它不会提醒你进行截断操作。

当使用char数据类型时,会使用空格填满少于制定长度的空间,这些空格会根据不同应用程序显示不同的表现形式。如果这些空格为报表的应用带来了麻烦,则可以在查询语句中使用截断函数或使用varchar数据类型。

7.文本和图像数据类型

可以使用文本和图像数据类型存储大量字符数据和二进制数据。在文本和图像数据类型中可以存储2000000个以上的字节,预先为文本和图像数据类型分配极大的存储空间是一种浪费,所以一般先为它们分配一部分空间,其余的进行动态分配。

图像数据类型有时用于作为行的一部分的内嵌OLE对象。

❑ text数据类型:使用text数据类型存储大量的文本信息。存储在text数据类型中的字符是可以直接输出到设备或打印设备的字符。在text数据类型中可以存储1~2147483647个字节的数据。数据存储在最初分配为2K字节固定长度的单元中,而其他2K字节的单元是动态加入并连接的。2K的数据页是指逻辑页,而不是指物理页。使用INSERT语句向文本列插入数据时,必须使用单引号引起数据。

❑ image数据类型:可以使用image数据类型存储1~2147483467个字节的比特类型的数据。例如,可以在一行的单列中存储图片、照片、画片等。

❑ 文本和图像列的限制:使用存储在文本或图像列中的数据时,可能会遇到几个限制。只可以使用文本和图像数据类型定义表列,而不能用他们定义其他的数据结构,如本地变量或参数。

存储在文本和图像列中的数据量使得在许多SQL语句中使用和操作这些数据类型时都不太方便,这是因为他们存储的数据量太大了。不能在ORDER BY、GROUP BY或计算从句中指定文本或图像数据类型的表列,SQL Server不会使用包括4000000个字节的列来排序或分组。

再就是,不能在UNION中使用文本或图像数据类型的列,除非是一个UNION ALL。也不能使用一个文本或图像数据类型返回数据值的子查询。在WHERE或HAVING从句中,不能使用文本或图像列,除非使用了比较操作符LIKE。也不能在文本或图像列上指定DISTICT。

最后,不能在文本或图像列上创建索引、主键或外键。

8.日期和时间数据类型

有两个数据类型存储日期和时间的组合信息,你会发现将日期和时间数据存储在这些数据类型中比将它们存储在字符型数据类型中要方便,如果将日期和时间存储在这两个数据类型中显示他们非常方便,因为SQL Server可以自动按熟悉的形式对它们进行格式化,你还可以使用特殊的日期和时间函数操作存储在这些数据类型中的值。

如果使用字符数据类型存储日期和时间,则SQL Server就不会自动对它们进行格式化。

日期和时间数据类型主要包括:

1)datetime数据类型

可以使用这个数据类型定义表列的存储结构。在这个数据类型中可以存储从1/11753AD~12/31/ 9999AD的日期和时间。

这个数据类型的总存储空间为8个字节。SQL Server使用前4个字节存储在1900年1月1日前或后的天数。作为负数存储的值代表这个日期前的天数,作为正数存储的值代表这个日期后的天数,时间存储在后4个字节中。

数据类型datetime的值存储精度为每秒的1/300。例如,1~3毫秒的值都表示为0毫秒;4~6毫秒的值表示为3毫秒。

当检索在datetime数据类型中的值时,显式的默认值为MMM DD YYYY hh : mm AM/PM,如OCT 23 1985 1:00 PM。当这个数据类型的值用于SQL语句时,必须用单引号将他们括起来,因为这样SQL Server才会重新组织各个部分和准确存储值。

当输入datatime值时,可以使用大小写的形式输入日期,并在月、日和年间使用一个或多个空格,如果输入日期而没有时间,默认时间为12:00 AM,如果你忽略日期和时间,则默认值为January 1,1900 12:00 AM。

可以以几种方法输入日期。每种都可以由SQL Server正确组织和存储。例如,可以以字母格式输入日期,使用月的缩写或全名。

如果输入的日期是忽略的世纪部分,则小于50年的时间在21世纪,而大于50年的时间在20世纪,如果输入的世纪值和默认值不一样,则必须输入指定的世纪值;当输入一个没有天的日期时,默认输入值是月的第一天。

为了能够让读者清楚地了解哪些输入方式是正确的,下面列举几种正确的输入方式:

❑ Sep 23 1983。

❑ SEP 23 1983。

❑ September 23 1983。

❑ sep 1983 23。

❑ 1983 sep 23。

❑ 19883 23 sep。

❑ 23 sep 1983。

datetime数据类型值的数字格式允许在不同时间单位使用斜线(/),划线(-)和小数点(.)。当使用带格式的datetime值时,必须指定这个值的月、日和年各部分。

以数字格式输入datetime值时,需要以正确的顺序输入日期的各个部分,否则可能返回错误消息告诉你输入的日期超出了实际的日期范围。

在下面的例子中,输入了几个数字形式的datetime数据类型的日期值,设置的日期格式为月、日和年,设置的语言为US-English。

❑ 6/24/71。

❑ 06/24/71。

❑ 6-24-1971。

❑ 6.24.1971。

如果你输入一个6位或8位没有分开的数字的值,总是按年、月、日的顺序进行解释的。月和日总是解释为两个数字。

如果在向表中输入一个新行时,忽略一个定义为datetime数据类型列的输入,则在这个新行中,列显示的值为January 1,1900,12 midnight。

必须按以下的顺序输入时间部分的值:小时、分钟、秒、毫秒。在各个时间部分间必须有分隔符号以识别时间部分的各个数字。可以使用AM或PM指定上午或下午。

我们还可以使用小数点或划线部分,它会影响毫秒单位的解释。

2)smalldatetime数据类型

Smalldatetime是另外一种存储日期和时间的数据类型,在这个数据类型中,你可以存储从1/11900AD~6/6/2709AD的日期和时间。

这个数据类型的总存储空间是4个字节。SQL Server使用两个字节存储January 1,1900后的天数。时间存储在另外两个字节中,按照零后的分钟数计算。所以这个数据类型的精度是1分钟,你可以使用这个数据类型存储比datetime数据类型精度稍低的时间值。使用smalldatetime数据类型所花费的存储空间是datetime数据类型的一半。

3.2.3 自定义数据类型

我们在对表列的数据类型进行定义时,除了可以使用系统提供的数据类型外,还可以根据需要用自定义的数据类型来进行定义。

用户自定义数据类型和系统的标准数据类型最大的区别在于,用户自定义数据类型是以标准系统数据类型为基础的,也就是说我们在自定义自己的数据类型时必须使用标准的系统数据为前提,在它们的基础上加一些限制条件创造出属于自己的一种数据类型。这种用户自定义数据类型只是对已有数据的一种描述方式,并不是一种新的数据类型,利用它可以加强对数据库字段数据类型的一致性维护,它在整个数据库中有效,不过很遗憾的是,在用户自定义数据类型建立之后其属性就不能直接更改,我们需要先删除之后再进行创建,但是如果该自定义数据类型已经被引用,我们就无法执行删除操作。下面介绍用户自定义数据类型的创建和删除。

我们可以使用两种方式来对用户自定义数据类型进行创建,一种方法是使用对象资源管理器进行可视化创建,另外一种是通过SQL编程的方式来进行创建,其实后面的很多操作都是使用这两种方式完成的。

1.使用对象资源管理器创建用户自定义数据类型

我们前面已经了解了对象资源管理器,它的主要作用就是给数据库管理系统提供一个用户界面,利用这个界面对数据库进行一系列的操作,下面看一下我们使用对象资源管理器进行用户自定义数据类型创建的主要过程。

(1)单击当前数据库节点下的“类型”节点。然后用鼠标右键单击该节点下的“用户定义数据类型”节点,在弹出的快捷菜单中选择“新建用户定义数据类型”命令,如图3.1所示。

图3.1 选择“用户新建用户定义数据类型”命令

(2)弹出“新建用户定义数据类型”对话框,可以在该对话框中创建自己所需的数据类型。例如,通过该对话框创建数据类型TestType,如图3.2所示。

图3.2 创建数据类型TestType

(3)单击“确定”按钮,完成用户自定义数据类型的创建。

2.通过SQL编程方式来创建用户自定义数据类型

我们可以使用系统存储过程sp_addtype来创建自定义数据类型,至于什么是存储过程,读者在这里不必深究,在后面的章节中我们会对它进行详细介绍。下面先了解该存储过程的使用语法。

        sp_addtype type, [ system_data_type ]   [ ,'nulltype' ]

❑ type:用户定义数据类型的名称。数据类型名称必须遵循标识符规则,并且在每个数据库中必须是唯一的。

❑ system_data_type:SQL server提供的数据类型,用户定义的数据类型即基于该类型。

❑ nulltype:指定如何处理null值。设置null默认、not null或nonull。

例如,我们要建立自定义数据类型TestType,就可以使用以下语句进行操作。

        sp_addtype TestType, 'NUMERIC (4,0)','NONULL'

那么我们怎样运行这句代码让它在指定数据库中发挥作用呢?当然这里就要用到SQL Server 2005给我们提供的另外一个组件工具——查询编辑器。具体的操作步骤如下:

(1)单击“新建查询”按钮,新建一个SQL查询,并且选择要进行操作的数据库,如图3.3所示。

图3.3 新建SQL查询

(2)将操作脚本书写到新建的查询界面中,并且单击“执行”按钮即可完成用户自定义数据类型的添加。如图3.4所示。

图3.4 执行操作脚本

同样删除用户自定义数据类型也有两种方式,在使用对象资源管理器进行操作时,直接用鼠标右键单击已经创建的用户自定义数据类型,然后选择“删除”命令即可,如图3.5所示。

图3.5 利用对象资源管理器删除用户自定义数据类型

我们还可以利用SQL脚本对用户自定义数据类型进行删除操作,基本的SQL语法为:

        sp_droptype type

type即为用户定义数据类型的名称。

具体执行过程和创建自定义数据类型类似,我们也是利用查询分析器来进行操作的。

在执行用户自定义的删除操作时还有一个值得注意的地方,那就是如果用户自定义数据类型在数据库中的某个地方使用,就不能执行删除操作。

3.3 变量

变量是一种语言中必不可少的组成部分。在SQL Server依赖的Transact-SQL语言中有两种形式的变量,一种是用户自己定义的局部变量,另一种是系统提供的全局变量。在SQL语言中和变量相关的概念还有批和脚本的概念,下面我们就先介绍批和脚本的概念,然后再介绍变量。

3.3.1 批和脚本

在SQL Server中为了方便变量及函数的处理提出了批和脚本的概念,批就是一条或者多条SQL语句的集合,而脚本则是按照一系列顺序提交的批。通过这两个概念我们可以非常清晰地了解SQL语句之间的关系,便于我们对SQL语句的管理。

1.批

一个批是由一条或多条SQL语句组成的语句集,这些语句一起提交并作为一个组来执行。SQL Server将批中的语句作为一个整体编译为一个执行计划。因为批中的语句是一起提交给服务器的,所以可以节省系统开销。

在查询分析器中,可以用GO命令标志一个批的结束。GO不是一个执行语句,是通知查询分析器有多少语句要包含在当前的批中。查询分析器将两个GO之间的语句组成一个字符串交给服务器去执行。

如,以下代码包含3个批:

        USE Test
        GO
        CREATE VIEW V_STUDENTS
        AS
        SELECT id,name
        FROM students
        WHERE id='001'
        GO
        SELECT *
        FROM V_STUDENTS
        GO

也就是每个GO的位置就是一个批结束的位置。

因为SQL Server为一个批生成一个单独的执行计划,所以一个批本身应该是完整的,不能在一个批中引用其他批定义的变量,也不能将注释从一个批开始,在另一个批中结束。

如果批中的语句出现编译错误,那么将不能生成执行计划,批中的任何一个语句都不会执行。

批运行时期的错误,如果是多数,则终止当前语句和批中后继语句的执行,少数运行时期错误(如违反约束),只会影响当前造成错误的语句,而其后的语句仍可以正常执行。不论是哪种运行时期错误,出错之前的语句的执行结果不会受到影响,除非该批位于一个事务中,而且在出现错误之后明确地将事务回滚。

批有如下限制:

❑ CREATE DEFAULT、CREATE PROCEDURE、CREATE RULE、CREATE TRIGGER和CREATE VIEW语句不能与其他语句位于同一个批中。

❑ 不能在一个批中修改一个表的结构,然后在同一个批中引用刚修改的新列。

❑ 如果批的第一条语句是EXECUTE,则EXECUTE关键字可以省略。否则,不能省略。

2.脚本

脚本是一系列顺序提交的批。脚本可以直接在查询分析器等工具中输入并执行,也可以保存在文件中,再由查询分析器等工具执行。

一个脚本可以包含一个或多个批,脚本中的GO命令标志一个批的结束,如果一个脚本没有包含任何GO命令,那么它被视为一个批。

脚本可用于:

❑ 将服务器上创建一个数据库的步骤永久地记录在脚本文件中。

❑ 将语句保存为脚本文件,从一台计算机传递到另一台计算机,这样可以方便地使两台计算机执行同样的操作。

3.3.2 局部变量

局部变量是用户自定义的变量。使用范围是定义它的批、存储过程或触发器。局部变量的作用范围仅限制在程序内部。局部变量可以作为计数器来计算循环执行的次数,或是控制循环执行的次数。另外,利用局部变量还可以保存数据值,以供控制流语句测试及保存由存储过程返回的数据值等。局部变量前面通常加上“@”标识。用DECLARE对局部变量进行定义,并指明此变量的数据类型,用SET或SELECT命令对其赋值。局部变量的数据类型可以是用户自定义的数据类型,也可以是系统数据类型,但不能将其定义为TEXT或IMAGE数据类型。

1.定义局部变量

定义局部变量的语法如下:

        DECLARE @local_variable data_type [,local_variable data_type]…

其中local_variable代表定义的局部变量的名称。

data_type代表定义的变量类型。

可以看出,DECLARE命令可以定义多个局部变量,之间用逗号分隔。

2.用SELECT为局部变量赋值

用SELECT为局部变量赋值的语法如下:

        SELECT { @local_variable = expression } [ ,…n ]

其中参数@local_variable是给其赋值的声明变量。expression是任何有效的SQL Server表达式,包括变量子查询。

SELECT命令可以将一个表达式的值赋给一个局部变量,也可以将一个SELECT查询的结果赋给一个局部变量。

SELECT命令通常返回一个值给局部变量。但当返回多个值时也不会出现错误。例如,当expression为一个表列的名字时,SELECT命令可能会返回多个值,则变量的值为最后一个返回值。如果SELECT命令没有返回值,则局部变量保持原值不变,如expression为—个分级查询且没有返回值时,变量被置为NULL。

3.用SET为局部变量赋值

SET命令的功能非常丰富,语法格式也灵活多样,用SET为局部变量赋值的常用语法格式为:

        SET @local_variable= expression

SET命令和SELECT命令都可以使用表达式为变量赋值。它们之间的主要异同在于:

❑ SELECT可以从表、子查询或者视图中查询数据,并且也可以包含其他SELECT子句;而SET命令则只能从表达式中获取数据。

❑ SET和SELECT命令中都可以使用函数。

❑ SELECT语句可以查询多列,而每个列中的数据都可以赋值给一个变量。如果SELECT语句返回了多个行,将会把结果集中最后一行的数据赋值给变量,系统不会报告任何错误。

3.3.3 全局变量

全局变量是由SQL Server系统提供并赋值的变量。用户不能建立全局变量,也不能修改全局变量的值。与局部变量不同,全局变量在所有存储过程内均有效。通常将全局变量的值赋给局部变量,以便保存和处理。在使用全局变量时请注意以下规则:

❑ 全局变量是在服务器级定义的,不是由用户例程定义的。

❑ 用户只能使用系统预定义的全局变量。

❑ 引用全局变量时,前面一定加上“@@”标识。

❑ 用户不能定义与系统全局变量同名的局部变量,否则将产生不可预测的结果。

❑ 全局变量以两个at(@)开头,下面我们对SQL Server中的预定义全局变量进行简单的说明。

@@servername:返回运行SQL Server数据库本地服务器的名称。

@@remserver:返回登录记录中记载的远程SQL Server服务器的名称。

@@connections:返回自上次启动SQL Server以来连接或试图连接的次数,用其可让管理人员方便地了解今天所有试图连接服务器的次数。

@@cursor_rows:返回最后连接上并打开的游标中当前存在的合格行的数量。

@@erro:返回最后执行的Transact-SQL语句的错误代码。

@@rowcount:返回受上一语句影响的行数,任何不返回行的语句将这一变量设置为0。

@@version:返回SQL Server当前安装的日期、版本和处理器类型。

@@cup_busy:返回自SQL Server最近一次启动以来CPU的工作时间,单位为毫秒。

@@datefirst:返回使用SET DATEFIRST命令而被赋值的DATAFIRST参数值。SET DATEFIRST命令用来指定每周的第一天是星期几。

@@DBTS:返回当前数据库的时间戳值必须保证数据库中时间戳的值是唯一的。

@@FETCH_STATUS:返回上一次FETCH语句的状态值。

@@IDENTITY:返回最后插入行的标识列的列值。

@@IDLE: 返回自SQL Server最近一次启动以来CPU处于空闭状态的时间长短,单位为毫秒。

@@IO_BUSY:返回自SQL Server最后一次启动以来CPU执行输入、输出操作所花费的时间(毫秒)。

@@LANGID:返回当前所使用的语言ID值。

@@LANGUAGE:返回当前使用的语言名称。

@@LOCK_TIMEOUT:返回当前会话等待锁的时间长短,单位为毫秒。

@@MAX_CONNECTIONS:返回允许连接到SQL Server的最大连接数目。

@@MAX_PRECISION:返回decimal和numeric数据类型的精确度。

@@NESTLEVEL:返回当前执行的存储过程的嵌套级数,初始值为0。

@@OPTIONS:返回当前SET选项的信息。

@@PACK_RECEIVED:返回SQL Server通过网络读取的输入包的数目。

@@PACK_SENT:返回SQL Server写给网络的输出包的数目。

@@PACKET_ERRORS:返回网络包的错误数目。

@@PROCID:返回当前存储过程的ID值。

@@SERVICENAME:返回SQL Server正运行于哪种服务状态之下,如MS SQLServer、MSDTC、SQLServerAgent。

@@SPID:返回当前用户处理的服务器ID值。

@@TEXTSIZE:返回SET语句的TEXTSIZE选项值,SET语句定义了SELECT语句中text或image。数据类型的最大长度基本单位为字节。

@@TIMETICKS:返回每一时钟的微秒数。

@@TOTAL_ERRORS:返回磁盘读写错误的数目。

@@TOTAL_READ:返回磁盘读操作的数目。

@@TOTAL_WRITE:返回磁盘写操作的数目。

@@TRANCOUNT:返回当前连接中处于激活状态的事务数目。

3.4 SQL的佐料——运算符

为了实现编程的功能,与其他高级语言一样,Transact-SQL运用运算符和函数实现各种计算和处理功能。

Transact-SQL提供了如下几种类型的运算符:算术运算符、比较运算符、字符连接运算符、逻辑运算符、按位运算符。

3.4.1 算术运算符

算术运算符对两个表达式执行数学运算,这两个表达式可以是数值数据类型类别的一个或多个数据类型,其种类和含义如表3.3所示。

表3.3 SQL语言中的算术运算符

对于算术运算符这里有两点需要说明:

❑ 加(+)和减(-)运算符也可用于对datetime和smalldatetime值执行算术运算。

❑ 取模运算符的作用是返回一个除法运算的整数余数,例如,12%5=2,这是因为12除以5,余数为2。

3.4.2 比较运算符

在SQL语言中,比较运算符能够进行除text、ntext和image数据类型之外的其他数据类型表达式的比较操作。比较运算表达式的返回值为布尔数据类型,即TRUE、FALSE。

SQL语言中的比较运算符主要包括等于、大于、小于、大于或等于、小于或等于、不大于、不小于、不等于,控制实行优先级——小括号。

1.=(等于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的值等于右边的操作数,则结果为TRUE,否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SET ANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

2.>(大于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的值大于右边的操作数,则结果为TRUE;否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SET ANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

3.<(小于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的值小于右边的操作数,则结果为TRUE;否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SET ANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

4.>=(大于或等于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的值大于或等于右边的操作数,则结果为TRUE;否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SETANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

5.<=(小于或等于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的值小于或等于右边的操作数,则结果为TRUE;否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SET ANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

6.!>(不大于)

这个操作符的作用正好和>(大于)操作符的作用相反。

7.!<(不小于)

这个操作符的作用正好和<(小于)操作符的作用相反。

8.<>、!=(不等于)

比较两个表达式(比较运算符)。当比较非空表达式时,如果左边操作数的数值不等于右边的操作数,则结果为TRUE;否则结果为FALSE。如果在两个操作数中有一个或者两个都为NULL,并且SET ANSI_NULLS被设置为ON,则结果为NULL。如果SET ANSI_NULLS被设置为OFF,则当一个操作数为NULL时结果为FALSE,当两个操作数都为NULL时结果为TRUE。

9.()(控制实行优先级)

通过这个运算符可以提高表达式的优先级,使这个表达式的优先级达到最高。

3.4.3 逻辑运算符

逻辑运算符用于测试条件是否为真,根据测试结果返回布尔值TURE、FALSE或UNKNOWN。

❑ AND:对两个布尔表达式的值进行逻辑与运算,如果其中有一个为TURE,另一个为UNKNOWN,或两个都为UNKNOWN,则返回值为UNKNOWN。

❑ OR:对两个布尔表达式的值进行逻辑或运算,如果其中有一个为FALSE,则另一个为UNKNOWN,或两个都为UNKNOWN,则返回UNKNOWN。

❑ NOT:对布尔表达式的值进行取反运算,当其值为UNKNOWN时,返回值为UNKNOWN。

❑ ALL:如果一组的比较都为TRUE,那么就为TRUE。

❑ ANY:如果一组的比较中任何一个为TRUE,那么就为TRUE。

❑ BETWEEN:如果操作数在某个范围之内,那么就为TRUE。

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

❑ IN:如果操作数等于表达式表列中的一个,那么就为TRUE。

❑ LIKE:如果操作数与一种模式相匹配,那么就为TRUE。

❑ SOME:如果在一组比较中,有些为TRUE,那么就为TRUE。

3.4.4 连接运算符

连接运算符是指可以将一个或多个文本连接为一个组合文本的运算符号,在SQL语言中连接运算符只有一种,即“+”。但是这时“+”运算符的含义不是加法,而是字符串的连接,例如:

        fullName=”givenName”+” ”+”familyName”

这句话我们就是使用了连接运算符“+”生成了一个新的字符串fullName,这个fullName的值就是“givenName familyName”。

3.4.5 按位运算符

按位运算符对整数或二进制数据进行按位与(&)、或(|)、异或(^)、求反(~)等逻辑运算。

1.&(位与)

上下运算,按照与的运算规则:0&0=0 ;0&1=0;1&1=1。

例如:

170 & 75结果为0000 0000 0000 1010。

再把二进制数转换为十进制数10。

2.~(位非)

运算法则:0变1,1变0。

~170的二进制:1111 1111 0101 0101, 十进制为:-171。

~75的二进制:1111 1111 1011 0100, 十进制为:-76。

3.|(位或)

上下运算,按照与的运算规则:0&0=0 ;0&1=1;1&1=1。

例如:

170 & 75结果为0000 0000 1110 1011。

再把二进制数转换为十进制数235。

4.^(位异或)

上下运算,按照与的运算规则:0&0=0 ;0&1=1;1&1=0。

例如:

170 & 75结果为0000 0000 1110 0001。

再把二进制数转换为十进制数225。

3.4.6 运算符的优先级

在实际的SQL语言编程中,可能在一个运算符中出现多个运算符,那么在计算时,就按照优先级级别的高低进行计算,级别高的运算符先计算,级别低的运算符后计算,具体运算符的优先级如表3.4所示。

表3.4 SQL语言中的优先级级别

3.5 认识表达式

表达式在SQL语言中起着非常重要的作用,可以说是整个SQL语言的核心部分,因为SQL语言中的很多重要操作都需要表达式来完成,这一节我们主要目的就是让读者对表达式有一个大致的认识,关于表达式的详细内容我们会在以后的章节中渐渐地深入了解。

3.5.1 什么是表达式

表达式是指用运算符和圆括号把常量、变量和函数等运算成分连接起来的有意义的式子,要特别指出的是单个的常量、变量、函数也可以看成是一个表达式。

SQL语言的核心就是SQL表达式,表达式可用于很多方面,如执行计算、检索控件的值或向查询提供条件等。 在后面的章节中SQL表达式会随处可见,特别是下一章——“走进SQL语句的世界”中大部分SQL语句都是由SQL关键字加上SQL表达式组成的。在这里我们只需先了解SQL语句的简单概念和分类,具体的介绍我们在下一章展开。

3.5.2 SQL表达式的分类

对于SQL表达式的分类我们可以有两种分类方法,一种是按照连接表达式的运算符进行分类,我们可以将表达式分为算术表达式、比较表达式、逻辑表达式、按位表达式和混合表达式等;另一种分类方法是按照表达式的作用来进行分类,我们可以将表达式分为字段名表达式、目标表达式和条件表达式。

对于第一种分类方法就是按照连接运算因子的运算符进行划分的,我们很容易就能够理解,这里就不在进行过多的阐述,下面我们按照第二种分类方式简单介绍SQL表达式。

1.字段名表达式

字段名表达式可以是单一的字段名或几个字段的组合,还可以是由字段、作用于字段的集函数和常量的任意算术运算(+、-、*,/)组成的运算公式。主要包括数值表达式、字符表达式、逻辑表达式、日期表达式4种。

2.目标表达式

目标表达式有4种构成方式。

❑ *:表示选择相应基表和视图的所有字段。

❑ <表名>.*:表示选择指定的基表和视图的所有字段。

❑ 集函数():表示在相应的表中按集函数操作和运算。

❑ [<表名>.]<字段名表达式>[,[<表名>.]<字段名表达式>]…:表示按字段名表达式在多个指定的表中选择。

3.条件表达式

条件表达式常用的有以下6种。

1)比较大小应用比较运算符构成表达式,主要的比较运算符有=、>、<、>=、<=、!=、<>、!>(不大于)、!<(不小于)、NOT+(与比较运算符同用,对条件求非)。

2)指定范围

        BETWEEN…AND… ,NOT BETWEEN…AND…

查找字段值在(或不在)指定范围内的记录。BETWEEN后是范围的下限(即低值),AND后是范围的上限(即高值)。

3)集合

        IN…,NOT IN…

查找字段值属于(或不属于)指定集合内的记录。

4)字符匹配

        LIKE,NOT LIKE'<匹配串>'[ESCAPE'<换码字符>']

查找指定的字段值与<匹配串>相匹配的记录。<匹配串>可以是一个完整的字符串,也可以含有通配符“_”和“%”。其中“_”代表任意单个字符;“%”代表任意长度的字符串。

5)空值

        IS NULL,IS NOT NULL

查找字段值为空(或不为空)的记录。NULL不能用来表示无形值、默认值、不可用值,以及取最低值或取最高值。SQL规定,在含有运算符+、-、*、/的算术表达式中,若有一个值是空值,则该算术表达式的值也是空值;任何一个含有NULL比较操作结果的取值都为“假”。

6)多重条件

        AND,OR

AND含义为查找字段值满足所有与AND相连的查询条件的记录;OR含义为查找字段值满足查询条件之一的记录。AND的优先级高于OR,但可通过括号改变优先级。

3.6 SQL利器——通配符

在搜索数据库中的数据时,可以使用SQL通配符。SQL通配符在搜索数据库中的数据时, SQL通配符可以替代一个或多个字符。需要特别注意的是,SQL通配符必须与LIKE运算符一起使用。在SQL语言中我们通常使用的通配符有以下几种:

❑ %:包含零个或更多字符的任意字符串。例如:LIKE'%A%'可以查找任意位置的、包含字母A的所有项目。

❑ _(下画线):任何单个字符。例如,LIKE'_B'将查找以b结尾的所有两个字母的项目(如AB、CB等)。

❑ [ ]:指定范围 ([a-f]) 或集合 ([abcdef]) 中的任何单个字符。例如,LIKE '[A-D]B' 将查找以字母B结尾且以介于A~D之间(包括起始字符)的任何单个字符开始的项目,如AB、CB等。

❑ [^]或[!]:不属于指定范围 ([a-f])或集合([abcdef])中的任何单个字符。例如,LIKE 'AB[^1]%'将查找以AB开始且其后的字母不为l的所有项目。

3.7 SQL语言中的注释

和大多数的高级编程语言一样,SQL语言也有自己的代码注释的标准与规则。注释的好处是让你的代码变得更加清晰和易于理解,对SQL代码加上注释之后不仅能够让自己很容易地理解自己以前写过的代码,更重要的是在团队协作开发的时候,确保你所交付给同伴的源码能够易于被读懂,从而不必花费大量的精力在代码的交接上。

SQL中的注释方法大致分为以下两种。

1.单行注释

很容易理解单行注释的作用,肯定是某一特定行的代码注释,指明该行代码的作用。单行代码的注释是以“--”开头的,如下所示:

        --单行注释内容

单行注释在编译的时候是被忽略的。

2.多行注释

多行注释是为了注释某一代码块的作用,SQL语言的多行注释是以“/*”开头,以“*/”结束的,如下所示:

        /*多行注释内容*/

3.8 小结

通过本章的学习我们对SQL语言有一个大致的了解了,更加具体和详细的内容我们会在后面的章节中进行详细的阐述。

本章我们主要学习了SQL语言中的数据类型、变量、运算符、表达式,以及其他一些辅助的与SQL语言开发相关的内容。在本章的讲述中读者可以非常清楚地理清讲解的思路,本章的讲解思路清晰、重点突出,我们把SQL语言中的数据类型、运算符、表达式等内容进行了详细的阐述,它们在我们今后的使用中会经常出现,是我们进行SQL编程的重点内容,也是基础内容,我们只有充分地理解它们,才能在后面的学习中游刃有余。下一章我们将进行SQL语句的学习,这是SQL Server中一个非常中心的内容,SQL语句的编写在很大程度上可以说是SQL语言的具体应用。

3.9 习题

1.简述SQL语言的特点。

2.试论述SQL Server系统数据类型的分类,以及各种数据类型的特点。

3.使用对象资源管理器和SQL语句两种方式创建一个自定义数据类型,让这个自定义数据类型满足:基本数据类型为varchar,长度为80,不能为空值。

4.区分局部变量和全局变量。

5.试论述SQL Server运算符的分类,以及每一种运算符的用途和特点。