2.5 常量、变量、函数和表达式
在数据库业务数据处理过程中,标识符、常量、变量、函数和表达式的概念和使用方法是必不可少的知识,复杂的函数、触发器和存储过程也是由上述语句构成的。本节将对标识符、常量、变量、函数和表达式的概念和用法进行详细讲解。
2.5.1 标识符及使用规则
在SQL中,标识符是指用于标识数据库对象名称的字符串。在SQL Server中,所有的数据库对象都可以有标识符,如服务器、数据库、表、视图、索引、触发器和存储过程等。一般情况下,操作数据库对象时都需要标识符,如查询指定表的数据必须指定查询表的表名;但是也有一些对象的标识符是可选的,如创建约束时用户可不提供标识符,其标识符由系统默认生成。按照标识符的使用方法,标识符可分为两类:常规标识符和界定标识符。
1.常规标识符
常规标识符又称规则标识符,常规标识符的命名规则如下。
1)标识符由字母、数字、下画线、@符号、#和$符号组成,其中字母可以是英文字母a~z或A~Z,也可以是其他语言的字符,如表名:“学生信息表”。
2)标识符的首字符不能是数字或“$”符号。
3)标识符不能使用SQL的保留字,例如,命令sp_help或函数名max、min、desc、asc等。
4)标识符内能使用空格和特殊字符,如?、%、&和*等。
5)标识符的长度不能超过128个字符。
2.界定标识符
界定标识符又称分隔标识符,包括两种。
1)方括号或引号。对不符合标识符命名规则的标识符,例如,标识符中包含SQL Server关键字或包含了内嵌的空格和其他不是规则规定的字符时,要使用界定标识符([])或双引号(“”)来将标识符括起来。
2)空格和保留字。例如,在标识符[product name]和“insert”中,分别将界定标识符用于带有空格和保留字insert的标识符中。
说明:
1)符合标识符格式的标识符既可以使用分隔,也可以不分隔。但是,对于不符合格式规则的标识符必须进行分隔。例如,productName标识符既可以分隔也可以不分隔,分隔后的标识符为[productName];对于标识符product Type Name则必须进行分隔,分隔后的标识符为[product Type Name]或“product Type Name”。
2)需要使用分隔标识符的两种情况:①对象名称中包含Microsoft SQL Sever保留关键字时,则需要使用界定标识符,如[select];②对象名称中使用了未列入限定字符的字符,如[prodoct[1] table]。
3)引用标识符。默认情况下,只能使用括号分界定标识符。如果想使用引用标识符,需要将Quoted_Identifier标志设为ON。
【案例2-23】标识符示例。规则标识符示例:_Product、Company、课程信息表、Customer_01和Product_Type_Name等;不规标识符示例:tbl product、productName&123等。
2.5.2 数据类型
在SQL Server中,每个列、常量、变量、表达式和参数都有其各自的数据类型,指定对象的数据类型相当于定义了该对象的下列特性。
1)对象所含的数据类型,如字符、整数和二进制数。
2)每列所存储值的长度(宽度)或大小。
3)数值精度和小数位数(仅用于数值数据类型)。
SQL Server中提供了两类数据类型供用户选择:系统数据类型和用户自定义数据类型。系统数据类型由SQL Server提供系统数据类型集,定义可供使用的所有数据类型,用户可直接使用上述数据类型。如果出于方便性考虑或是当SQL Server内置的数据类型不能满足需要时,可以根据用户自己的实际需要在系统基本数据类型的基础上定义自己的数据类型,这就是用户自定义数据类型,用户定义数据类型是出于系统可扩展性的考虑。
SQL Server提供的系统数据类型如表2-23所示,详细的类型讲解请参看SQL Server数据类型手册。
表2-23 SQL Server系统数据类型
2.5.3 常量和变量
1.常量
常量是指在程序运行过程中其值保持不变的量。常量是表示一个特定数据值的符号,也称为文字值或标量值。常量的格式取决于它所表示的值的数据类型,具体的数据类型请参见表2-23。
根据不同的数据类型,常量可分为字符型常量、整型常量、日期常量、实型常量、货币常量和全局唯一标识符。
(1)字符型常量
字符型常量由字母、数字字符(a~z、A~Z和0~9)及特殊字符,如感叹号(!)、at符(@)和数字号(#)等字符组成。通常放在单引号内。如果字符型常量中包含单引号字符,需要使用两个单引号表示,例如,要定义一个字符型常量,其值为I'm a student,则要写作'I''m a student'。
字符常量有两种:ASCII和Unicode字符型常量。
1)ASCII字符型常量:用单引号引起来,由ASCII字符构成的字符串,如'abcd'。
2)Unicode字符型常量:通常在常量前面有一个N,如N'abcd'(其中的N在SQL92标准中表示国际语言,要求必须大写)。
(2)整型常量
整型常量通常表示整数。主要包括二进制整型常量、十进制整型常量和十六进制常量。例如,二进制,如1100;十进制,如2016;十六进制,如0x4b、0x5a等。
(3)日期时间型常量
表示日期或时间的常量,要求用单引号将所表示的日期或时间引起来。例如,'2016-08-09' 'July-10-1998' '08/24/1998'和'2016年8月9日'等。
(4)实型常量
表示定点数或浮点数,如126.35、5E10等。
(5)货币常量
以货币符号开头,如¥600.45。SQL Server不强制分组,每隔3个数字插入一个逗号进行分隔。
(6)全局唯一标识
全局唯一标识符(Globally Unique Identification Numbers,GUID)为十六进制字节的二进制数据类型,是SQL Server根据计算机网络适配器地址和主机时钟产生的唯一号码生成的全局唯一标识符。
2.变量
变量是指在程序运行过程中其值可以发生变化的量,包括局部变量和全局变量两种。
(1)局部变量
局部变量是由用户定义,是作用域局限在一定范围内的SQL对象。
作用域:若局部变量在一个批处理、存储过程或触发器中被定义,则其作用域就是此批处理、存储过程和触发器。
局部变量的声明:局部变量的声明语句格式如下。
DECLARE@变量名1 [AS] 数据类型,@变量名2 [AS] 数据类型,…,@变量名n [AS]数据类型。
注意:
1)局部变量名必须以@开头。
2)局部变量必须先定义,然后才能在SQL语句中使用,默认值为NULL。
3)数据类型要求:系统提供的类型、用户定义的数据类型或别名数据类型。变量不能是text、ntext或image数据类型。
局部变的赋值:局部变量的赋值语句的语法如下。
格式一:set@变量名=表达式
格式二:set@变量名=表达式
或,select@变量名=输出值from表where条件
或,select@变量名1=表达式1[,@变量名2=表达式2,…,@变量n=表达式n]
【案例2-24】select命令为变量赋值,并输出结果。
执行结果如图2-4所示。
【案例2-25】select查询返回多个结果,最后一个值赋给变量。
执行结果如图2-5所示。
图2-4 【案例2-24】执行结果
图2-5 【案例2-25】执行结果
【案例2-26】set语句的用法。
执行结果如图2-6所示。
图2-6 【案例2-26】执行结果
(2)全局变量
系统全局变量是SQL Sever系统定义并提供赋值的变量。用于跟踪服务器范围和特定会话期间的信息,不允许用户显式定义、赋值或修改,也就是说既不能定义全局变量,也不能使用set语句对全局变量进行赋值。
定义全局变量的格式如下。
SQL Server系统提供了33个全局变量,方便用户监测或了解SQL Server服务器活动状态。常用的全局变量如表2-24所示,更多内容可查阅SQL Server手册。
表2-24 常用系统全局变量
2.5.4 函数
函数是指具有完成某种特定功能的程序,在SQL编程中也可理解为能完成一定功能的SQL语句集合,其处理结果称为返回值,处理过程称为函数体。
SQL Server与其他程序设计语言一样,提供了丰富的内置函数,而且允许用户自定义函数。利用这些函数可以方便地实现各种运算和操作,一般函数的返回值返回select请示。下面对SQL Server的函数进行简要介绍。
1.SQL Server常用函数的用法
SQL Server提供的常用内置函数分为14类。每种类型的内置函数都可以完成某种类型的操作,其内置函数的分类如表2-25所示。
表2-25 SQL Server的内置函数种类和功能
(1)聚合函数
聚合函数又称为统计函数。所有的聚合函数均为确定性函数,只要使用一组特定输入值(数值型)调用聚合函数,该函数就会返回同类型的值。
SQL Server提供了大量聚合函数,聚合函数的名称和功能如表2-26所示。
表2-26 常用的聚合函数及功能
注意:在所有聚合函数中,除了COUNT函数以外,聚合函数均忽略空值。
【案例2-27】查询图书表中价格最高的图书。
执行结果如图2-7所示。
图2-7 【案例2-27】执行结果
(2)数学函数
数学函数用于对数字表达式进行数学运算并返回计算结果。SQL Server提供了20多个用于处理整数与浮点值的数学函数。表2-27列举了部分常用的数学函数及功能。
表2-27 常用的数学函数及功能
(续)
下面给出几个数学函数的常见示例。
(3)字符函数
字符函数又称为字符串函数,用于计算、格式化和处理字符串变量,或将对象转换为字符串。与数学函数类似,为了方便用户进行字符型数据的各种操作和运算,SQL Server提供了功能全面的字符串处理函数。表2-28对常用的字符串处理函数进行了简要介绍。
表2-28 常用的字符函数及功能
由于字符函数在实际编程中应用较为广泛,下面就表2-28中的每个函数给出相应的示例,示例如表2-29所示。
表2-29 常用的字符函数应用示例
(4)日期时间函数
SQL Server提供了9个日期时间处理函数。其中的一些函数接datepart变量,此变量指定函数处理日期与时间所使用的时间粒度。表2-30列出了datepart变量的可能设置。
表2-30 datepart常量
SQL Server提供的9个常用的日期时间函数如表2-31所示。
表2-31 常用的日期时间函数及功能
【案例2-28】日期时间函数示例。
1)dateadd函数示例,该函数有3个参数,第一个参数是增加时间的类型,包括天、月和年等;第二个参数是增加数量;第三个参数为要增加的日期,返回值为增加日期数量后的时间。
2)datediff函数。
3)DATENAME函数。
*2. 自定义函数
为了扩展性和方便用户,SQL Server提供了自定义函数功能。自定义函数可以接受零个或多个输入参数,其返回值是一个临时表或一个数值。但是需要特别指出的是,自定义函数不支持输出参数,如果要使用输出参数,可以考虑使用后面章节中的存储过程。
在SQL Server中,使用CREATE FUNCTION语句可创建自定义函数,根据函数返回值形式的不同,可创建3类自定义函数:标量值自定义函数、内联表值自定义函数和多语句表值自定义函数。
(1)标量值自定义函数
标量值自定义函数的返回值是一个确定类型的标量值,其返回值类型为除text、ntext、image、timestamp和table类型之外的任意类型,即标量值自定义函数返回的是一个数值。
定义标量值自定义函数的语法结构如下。
说明:
WITH子句指出了创建函数的选项。如果ENCRYPTION参数被指定,则创建的函数是被加密的,函数定义的文本将以不可读的形式存储在syscomments表中,任何人都不可查看该函数的定义,包括函数的创建者和管理员。
【案例2-29】在Libaray示例数据库中创建函数,根据读者卡号,查询该用户的借书数。
函数定义如下。
创建函数后执行以下语句。
执行结果如图2-8所示。
图2-8 【案例2-29】执行结果
(2)内联表值自定义函数
内联表值自定义函数是以表形式返回一个值,也就是说返回一个表的数据。内联表值自定义函数没有BEGIN…END语句块中包含的函数体,而是直接使用RETURNS子句,其中包含的SELECT语句将数据从数据库中筛选出,形成一个表。使用内联表值自定义函数可提供参数化的视图功能。
内联表值自定义函数的语法结构如下。
【案例2-30】在Libaray示例数据库中创建函数,根据读者卡号,查询该此读者所借的所有图书。
执行以下语句。
执行结果如图2-9所示。
图2-9 【案例2-30】执行结果
(3)多语句表值自定义函数
多语句表值自定义函数可看作标量值和内联表值自定义函数的结合体。此类函数的返回值是一个表,但与标量值自定义函数一样,有一个BEGIN…END语句块中包含的函数体,返回值的表中的数据是由函数体中的语句插入的。因此,其可以进行多次查询,对数据进行多次筛选与合并,弥补了内联表自定义函数的不足。
2.5.5 运算符及其用法
运算符是指具体的运算符号,用于执行算术运算、字符串连接、赋值,以及在字段、常量和变量之间进行比较。在SQL Server中,运算符主要有六大类:算术运算符、赋值运算符、比较运算符、逻辑运算符、连接运算符和按位运算符。运算符在表达式中起到连接变量、常量和函数的作用,同时在连接过程中存在一定的优先级。下面将对SQL Server中的运算和运算符的优先级进行简要论述。
1.运算符的种类
1)算术运算符。可以在两个表达式上执行数学运算,这两个表达式可以是任何数值数据类型。SQL Server中主要的算术运算符如表2-32所示。
表2-32 算数运算符
2)比较运算符。用来比较两个表达式的大小,表达式可以是字符、数字或日期数据,其比较结果是boolean值。SQL Server中主要的比较运算符如表2-33所示。
表2-33 比较运算符
3)逻辑运算符。可以把多个逻辑表达式连接起来测试,以获得其真实情况。返回带有TRUE、FALSE或UNKNOWN的boolean数据类型。SQL Server中主要的逻辑运算符如表2-34所示。
表2-34 逻辑运算符
4)连接运算符。加号(+)是字符串串联运算符,可以将两个或两个以上的字符串合并成一个字符串。
5)按位运算符。按位运算符在两个表达式之间执行位操作,这两个表达式可以为整数数据类型中的任何数据类型。SQL Server中主要的逻辑运算符如表2-35所示。
表2-35 按位运算符
此外,还有赋值运算符(=)和一元运算符(+(正)、-(负)、~(按位取反))。
2.运算符的优先级
运算符的优先级决定了运算符与变量、常量和函数相结合和运算的顺序,运算符的优先级从高到低如表2-36所示。如果两个运算符的优先级相同,则按照从左到右的顺序进行运算。
表2-36 运算的优先级
2.5.6 表达式
表达式是指由常量、变量或函数等通过运算符按规则连接起来的有意义的式子。表达式的运算常在“列与列”或者“变量”间进行。在SQL Server中,表达式主要分为4类:数学表达式、字符串表达式、比较表达式和逻辑表达式。下面分对这4类表达式进行说明。
1.数学表达式
数学表达式用于各种数字变量的运算。数字变量的类型有int、smallint、tinyint、float、real、money和smallmoney。用于数学表达式的符号主要为算术运算符(见表2-32)。
2.字符串表达式
字符串表达式由字母、符号或数字组成。在字符串表达式中,用“+”来实现字符或字符串的连接。在数据类型中,可用于字符串加法的数据类型有char、varchar、nvarchar、text,以及可以转换为char或varchar的数据类型。例如,在查询中执行【案例2-31】中的代码,则变量str的值为“JSP&Oracle”。
【案例2-31】字符串连接应用。
执行结果如图2-10所示。
图2-10 【案例2-31】执行结果
3.比较表达式
比较表式用于两个表达式的比较,常用的比较表达式运算符见表2-33。需要指出的是,比较表达式的执行优先级如同数学表达式一样,可以用“( )”来人为设置。
4.逻辑表达式
在逻辑表达式中,有3种连接符:AND、OR和NOT。
1)AND表达式。当所有表达式的值为真时,其逻辑表达式的值才为真;如果有一个返回值为“假”,则表达式的值为“假”。
2)OR表达式。只要有一个子表达式的返回值为“假”,则其逻辑表达式的值即为“假”。
3)NOT表达式。当表达式的值为“真”时,进行NOT运算后,其表达式值为“假”,反之亦然。
表达式运算的优先级遵循运算符的优先级,从高到低依次为NOT、AND、OR。逻辑表达式适用的数据类型主要为数值型类型,包括binary,varbinary,int smallint,tinyint和bit等,也适用于多个逻辑表达式的运算,只需要各个表达式的结果为TRUE或FALSE。
比较运算符或逻辑运算组合成的两个或多个表达式,其结果数据类型为boolean,且值只为以下三者之一:TRUE、FALSE、UNKNOWN。
讨论思考:
1)标识符有哪几种?其命名和使用规则分别是什么?
2)什么是常量?什么是变量?它们的种类有哪些?
3)常量和变量的区别是什么?
4)什么是函数?常用函数分为哪几类?其功能分别是什么?
5)SQL Server提供哪些种类的运算符?其优先级如何排列?