CHAPTER 第5章 T-SQL Transact-SQL(T-SQL)是微软公司在SQLServer数据库管理系统中对ANSISQL-99 标准的实现。在SQLServer数据库中,T-SQL 由数据定义语言(DDL)、数据操纵语言 (DML)、数据控制语言(DCL)和T-SQL增加的语言元素组成。T-SQL增加的语言元素将 其他3部分语句组织起来,构成T-SQL程序,完成用户操作数据库的特定功能。本章将介 绍T-SQL增加的语言元素。 5.1 常量、数据类型与变量 5.1.1 常量 常量指在程序运行过程中值不变的量。常量又称为字面量或标量。常量的使用格式取 决于其值的数据类型。 常量根据其值的数据类型分为字符串常量、整型常量、实型常量、日期和时间常量、货币 常量、唯一标识符常量。各类常量说明如下。 1.字符串常量 字符串常量分为ASCII码字符串常量和Unicode码字符串常量。 1)ASCII码字符串常量 ASCII码字符串常量是由ASCII码字符构成的符号串。ASCII码字符串常量要用单 引号括起来。 ASCII码字符串常量举例: 'China' 'How are you!' 'O''Bbaar' 如果单引号中的字符串包含单引号,可以使用两个单引号表示嵌入的单引号。 2)Unicode码字符串常量 Unicode码字符串常量与ASCII码字符串常量相似,但它前面有一个字母N 作为标识 符,代表SQL-92标准中的国际语言。N 必须大写。 Unicode码字符串常量举例: 1 42 SQLServer教程(第4版) N'China ' N'How are you!' 每个Unicode字符用两字节存储,而每个ASCII字符用一字节存储。 2.整型常量 整型常量按照表示方式又分为十六进制整型常量、二进制整型常量和十进制整型常量。 1)十六进制整型常量 十六进制整型常量用前辍0x 后跟十六进制数字串表示,例如0xEBF、0x12Ff、 0x69048AEFDD010E、0x(0x空十六进制常量)。 2)二进制整型常量 二进制整型常量即数字0或1,并且不使用引号。如果二进制整型常量为一个大于1 的数字,它将被转换为1。 3)十进制整型常量 十进制整型常量即不带小数点的十进制数,例如1894、2、+145345234、-2147483648。 3.实型常量 实型常量有定点表示和浮点表示两种方式。举例如下: 实型常量的定点表示举例: 1894.1204 2.0 +145345234.2234 -2147483648.10 实型常量的浮点表示举例: 101.5E5 0.5E-2 +123E-3 -12E5 4.日期和时间常量 日期和时间常量是用单引号将表示日期和时间的字符串括起来构成的。SQLServer 可以识别如下格式的日期常量: ● 字母日期格式,例如'April20,2000'。 ● 数字日期格式,例如4' /15/1998'、1' 998-04-15'。 ● 未分隔的字符串格式,例如2' 0001207'。 以下是时间常量的示例: '14:30:24' '04:24:PM' 以下是日期和时间常量的示例: 第5章 T-SQL 1 43 'April 20, 2000 14:30:24' 5.货币常量 货币常量是以$作为前缀的整型或实型常量。下面是货币常量的示例: $12 $542023 -$45.56 +$423456.99 6.唯一标识符常量 唯一标识符常量是用于表示全局唯一标识符(GloballyUniqueIdentifier,GUID)值的 字符串。可以使用字符串或十六进制数字串格式指定。例如: '6F9619FF-8A86-D011-B42D-00004FC964FF' 0xff19966f868b11d0b42d00c04fc964ff 5.1.2 数据类型 在SQLServer中,每个字段(列)、局部变量、表达式和参数根据其对应的数据的特性, 都有一个相关的数据类型。在SQLServer中支持系统数据类型和用户自定义数据类型,另 外,SQLServer还提供了用户自定义表数据类型。 1.系统数据类型 系统数据类型又称为基本数据类型。在3.3.2节已详细地介绍了系统数据类型,此处 不再赘述。 2.用户自定义数据类型 用户自定义数据类型可看作系统数据类型的别名。 在多表操作的情况下,当多个表中的列要存储相同类型的数据时,往往要确保这些 列具有完全相同的数据类型、长度和为空性(数据类型是否允许空值)。用户自定义数据 类型并不是真正的数据类型,而只是提高数据库内部元素和基本数据类型之间一致性的 机制。 【例1.5.1】 在图书借阅系统的xsbook数据库中创建了xs、book、jy这3个表。从这3 个表的结构可看出:xs表中的“借书证号”字段值与jy表中的“借书证号”字段值应有相同 的类型,均为字符型,长度可定义为8,并且不允许为空值。为了使用方便,并使含义明确, 可以先定义一个数据类型,命名为Library_card_num,用于描述“借书证号”字段的类型属 性,然后将xs表中的“借书证号”字段和jy表中的“借书证号”字段定义为Library_card_ num 数据类型。 自定义数据类型Library_card_num 如表1.5.1所示。重新设计的xs、jy表中的“借书 证号”字段如表1.5.2和表1.5.3所示。 SQLServer教程(第4版) 表1.1 自定义数据类型Lba_cr_n 5.irryadum 依赖的系统类型值允许的长度为空性 char 8 NOTNULL 表1.重新设计的xs表的“借书证号”字段表1.3 重新设计的jy表的“借书证号”字段 5.2 5. 字段名类型 借书证号Library_card_num 字段名类型 借书证号Library_card_num 通过本例可知,要使用自定义数据类型,首先应定义该数据类型,然后用该数据类型定 义字段或变量。创建用户自定义数据类型时应考虑如下3个属性: ● 新数据类型名称 。 新数据类型所依据的系统数据类型(又称为基类型) 。 ● ● 新数据类型的为空性 。 1)创建用户自定义数据类 型 创建用户自定义数据类型可以使用界面方式,也可以使用命令方式 。 使用对象资源管理器创建用户自定义数据类型的步骤如下 : (1)启动SQLServerManagementStudio,在对象资源管理器中展开“数据库”→ xsbook→“可编程性”,右击“类型”,在弹出的快捷菜单中选择“新建”→“新建用户定义数据 类型”命令,弹出“新建用户定义数据类型”对话框。 (2)在“名称”文本框中输入自定义的数据类型名称,如Library_card_num 。在“数据类 型”下拉列表框中选择自定义数据类型所依据的系统数据类型char。在“长度”数值框中输 入要定义的数据类型的长度8。其他选项使用默认值,如图1.1所示,单击“确定”按钮即 可完成创建。如果自定义数据类型允许空值,则选择“允许NULL 值”复选框。 5. 图1.1 “新建用户定义数据类型”对话框 5. 第5章 T-SQL 1 45 在SQLServer中,可以使用CRETAETYPE语句实现用户自定义数据类型的定义。 其语法格式如下: CREATE TYPE [架构名]自定义类型名 FROM 系统数据类型名[(精度[, 小数位数])] [NULL | NOT NULL] [;] 例如,定义描述“借书证号”字段的数据类型的T-SQL语句如下: CREATE TYPE Library_card_num FROM char(8) NOT NULL 2)删除用户自定义数据类型 使用界面方式删除用户自定义数据类型的主要步骤如下: 在对象资源管理器中展开“数据库”→xsbook→“可编程性”→“类型”→“用户定义数据 类型”,在其下选择dbo.Library_card_num,右击该项,在弹出的快捷菜单中选择“删除”命 令,打开“删除对象”对话框后单击“确定”按钮即可(实际不执行此操作)。 说明:如果用户自定义数据类型在数据库中被引用,删除该数据类型的操作将不被 允许。使 用命令方式删除用户自定义数据类型可以用DROPTYPE语句实现。其语法格式 如下: DROP TYPE [架构名]自定义类型名> [; ] 例如,删除前面定义的Library_card_num 类型的语句如下: DROP TYPE Library_card_num 3)利用用户自定义数据类型定义字段 在创建了用户自定义数据类型后,接着应考虑定义这种数据类型的字段,同样可以利用 对象资源管理器和T-SQL命令两种方式实现。读者可以参照第3章进行字段定义,不同点 只是数据类型为用户自定义数据类型,而不是系统数据类型。 例如,可以在对象资源管理器中使用用户自定义数据类型定义xs1表的“借书证号”字 段,如图1.5.2所示。 图1.5.2 使用用户自定义数据类型定义xs1表的“借书证号”字段 1 46 SQLServer教程(第4版) 利用命令方式定义xs1表结构的T-SQL语句如下: CREATE TABLE xs1 ( 借书证号 Llibrary_card_num NOT NULL PRIMARY KEY, 姓名char(8) NOT NULL, 性别bit NOT NULL DEFAULT 1, 出生时间date NOT NULL, 专业char(12) NOT NULL, 借书量int NOT NULL, 照片varbinary(MAX) NULL ) GO 3.用户自定义表数据类型 SQLServer还提供了用户自定义表数据类型。这种数据类型也是由用户自行定义的, 可以作为参数提供给语句、存储过程或者函数。创建用户自定义表数据类型也使用 CREATETYPE语句,语法格式如下: CREATE TYPE [架构名]自定义类型名 AS TABLE (列, … [表约束], …) 例如,创建用户自定义表数据类型,包含jy表中的所有列。T-SQL命令如下: CREATE TYPE jy_tabletype AS TABLE ( 借书证号 char(8) NOT NULL, ISBN char(18) NOT NULL, 索书号 char(10) NOT NULL PRIMARY KEY, 借书时间 date ) 用户自定义表数据类型的删除与用户自定义数据类型类似,可以在对象资源管理器中 使用界面方式删除,也可以使用DROPTYPE语句删除。 5.1.3 变量 变量用于临时存放数据,变量中的数据随着程序的运行而变化。变量在定义时必须有 名字及数据类型两个属性。变量名用于标识该变量,变量类型确定了该变量存放值的格式、 变量的取值范围及允许的运算。 1.变量的命名及分类 变量名必须是一个合法的标识符。 在SQLServer中,标识符分为两类: 第5章 T-SQL 1 47 (1)常规标识符。以ASCII字母、Unicode字母、下画线(_)、@或#开头,可后跟一个 或若干个ASCII码字符、Unicode码字符、下画线、货币符号($)、@或#,但不能全为下画 线、@或#。 注意:常规标识符不能是T-SQL 的保留字,不允许嵌入空格或其他特殊字符。 (2)分隔标识符。包含在双引号(")或者方括号([])内的常规标识符或不符合常规标 识符规则的标识符。 标识符允许的最大长度为128个字符。符合常规标识符格式规则的标识符可以用双引 号或方括号分隔,也可以不分隔。对不符合常规标识符规则的标识符必须进行分隔。 在SQLServer中,变量可分为两类: (1)全局变量。由系统提供且预先声明,通过在名称前加两个@符号以区别于局部变 量。T-SQL 全局变量作为函数引用。例如,@@ERROR 返回执行的上一个T-SQL语句 的错误号,@ @CONNECTIONS 返回自上次启动SQLServer以来连接或试图连接的 次数。 (2)局部变量。用于保存数据值,例如保存运算的中间结果、作为循环变量等。 当首字母为@时,表示该标识符为局部变量。当首字母为#时,表示该标识符为临时数 据库对象名。其中,若开头为一个#,表示该标识符为局部临时数据库对象名;若开头为两 个#,表示该标识符为全局临时数据库对象名。 2.局部变量 1)局部变量的定义 在批处理或过程中用DECLARE语句定义局部变量,所有局部变量在定义后均初始化 为NULL。 DECLARE语句的语法格式如下: DECLARE {@局部变量名数据类型[=变量值]} [, …] 2)局部变量的赋值 定义局部变量后,可用SET或SELECT语句给其赋值。 用SET语句赋值的语法格式如下: SET @局部变量名=值 使用SET 语句赋值的局部变量可以是除cursor、text、ntext、image、table以外的任何 类型的已定义的局部变量。值可以是任何有效的SQLServer表达式。 【例1.5.2】 创建局部变量@var1、@var2并赋值,然后输出变量的值。 DECLARE @var1 char(10), @var2 char(30) SET @var1='中国' /*一个SET 语句只能给一个变量赋值*/ SET @var2=@var1+'是一个伟大的国家' SELECT @var1, @var2 上面的语句的执行结果如图1.5.3所示。 【例1.5.3】 创建一个名为sex的局部变量,并在SELECT 语句中使用该局部变量查 1 48 SQLServer教程(第4版) 图1.5.3 局部变量定义、赋值和输出 询xs表中所有男生的借书证号和姓名。 DECLARE @sex bit SET @sex=1 SELECT 借书证号, 姓名 FROM xs WHERE 性别=@sex 【例1.5.4】 将例1.5.3的查询结果赋给变量。 DECLARE @student char(8) SET @student=(SELECT 姓名FROM xs WHERE 借书证号='131101') SELECT @student 用SELECT语句赋值的语法格式如下: SELECT {@局部变量名=值}, … 使用SELECT语句赋值时,局部变量可以是除cursor、text、ntext、image以外的任何类 型的已定义的局部变量。值可以是任何有效的SQL表达式,包含标量子查询。 SELECT语句通常用于将单个值赋给变量。如果值为列名,则返回多个值,此时将返 回的最后一个值赋给变量。如果SELECT 语句没有返回值,变量将保留当前值。如果表达 式是不返回值的标量子查询,则将变量设为NULL。一个SELECT 语句可以给多个局部 变量赋值。 【例1.5.5】 使用SELECT给局部变量赋值。 T-SQL语句如下: DECLARE @var1 nvarchar(30) SELECT @var1='刘丰' SELECT @var1 AS 'NAME' 【例1.5.6】 给局部变量赋空值。 T-SQL语句如下: DECLARE @var1 nvarchar(30) SELECT @var1='刘丰' SELECT @var1= ( SELECT 姓名 FROM xs WHERE 借书证号='131101' ) SELECT @var1 AS 'NAME' 第5章 T-SQL 1 49 3.局部游标变量 1)局部游标变量的定义 局部游标变量用DECLARE语句定义。其语法格式如下: DECLARE @游标变量名CURSOR, … CURSOR表示该变量是局部游标变量。 2)局部游标变量的赋值 利用SET语句给一个局部游标变量赋值,有3种情况: ● 将一个已存在并已赋值的局部游标变量的值赋给另一个局部游标变量。 ● 将一个已声明的游标名赋给指定的局部游标变量。 ● 声明一个游标,同时将其赋给指定的局部游标变量。 上述3种情况下赋值语句的语法格式如下: SET @游标变量名= @另一个游标变量名 /*情况1*/ | 游标名/*情况2*/ | CURSOR 子句/*情况3*/ 如果被赋值的游标变量先前引用了一个不同的游标,则删除先前的引用。 对于CURSOR关键字引导游标声明的语法格式及含义,请参考4.3节。 3)局部游标变量的使用步骤 局部游标变量的使用步骤为:定义局部游标变量→给局部游标变量赋值→打开游标→ 利用游标读取记录→使用结束后关闭游标→删除游标的引用。 【例1.5.7】 定义并使用局部游标变量。 T-SQL语句如下: DECLARE @CursorVar CURSOR /*定义局部游标变量*/ SET @CursorVar=CURSOR SCROLL DYNAMIC /*给局部游标变量赋值*/ FOR SELECT 借书证号, 姓名 FROM xs WHERE 借书证号LIKE '20%' OPEN @CursorVar /*打开游标*/ FETCH NEXT FROM @CursorVar WHILE @@FETCH_STATUS=0 BEGIN FETCH NEXT FROM @CursorVar /*通过游标读取记录*/ END CLOSE @CursorVar DEALLOCATE @CursorVar /* 删除对游标的引用*/ 4.表数据类型变量的定义与赋值 使用DECLARE语句定义表数据类型变量的语法格式如下: 1 50 SQLServer教程(第4版) DECLARE @table_variable_name [AS]TABLE(column_definition | table_constraint[, …]) 说明:table_variable_name表示要声明的表数据类型变量的名称。 【例1.5.8】 定义一个表数据类型变量并向其中插入数据。 T-SQL语句如下: DECLARE @var_table AS TABLE ( num char(8) NOT NULL PRIMARY KEY, name char(8) NOT NULL, sex bit NULL ) /*定义变量*/ INSERT INTO @var_table SELECT 借书证号, 姓名, 性别FROM xs /*插入数据*/ SELECT * FROM @var_table /*查看内容*/ 5.2 运算符与表达式 SQLServer提供如下几类运算符:算术运算符、位运算符、比较运算符、逻辑运算符、 字符串连接运算符、一元运算符和赋值运算符。通过运算符连接运算量构成表达式。 1.算术运算符 算术运算符在两个表达式上执行算术运算,这两个表达式可以是任何数字数据类型。 算术运算符有+(加)、-(减)、*(乘)、/(除)和%(求模)5种。+(加)和-(减)运算符 也可用于对datetime及smalldatetime类型的值进行算术运算。 2.位运算符 位运算符用于实现两个表达式之间的位操作,这两个表达式的类型可以是整型或与整 型兼容的数据类型(如字符型等,但不能为image类型)。位运算符如表1.5.4所示。 表1.5.4 位运算符 运算符名称运算规则运算名称 & 两个对应位的值均为1时结果为1,否则为0 按位与 | 两个对应位中至少有一个的值为1时结果为1,否则为0 按位或 ^ 两个对应位的值不同时结果为1,否则为0 按位异或 【例1.5.9】 在master数据库中,建立bitop表,并插入一行,然后对a字段和b字段上 的值进行位运算。 T-SQL语句如下: USE master GO