SQL语句只能按照既定的顺序执行,在执行过程当中不能根据某些中间结果有选择地或循环地执行某些语句块,不能像高级程序语言那样进行流程控制。为此,微软公司在SQL语言的基础上添加了流程控制语句,从而获得一种结构化程序设计语言——Transact-SQL。程序员
Transact-SQL即事务SQL,也简写为T-SQL,它是微软公司对关系数据库标准语言SQL进行扩充的结果,是SQL语言的超集。Transact-SQL支持全部的标准SQL语言操做。sql
做为一种标准的关系数据库语言,SQL几乎能够在全部的关系数据库上使用。但因为Transact-SQL是微软对SQL扩充的结果,因此只有SQL Server支持Transact-SQL,而其余关系数据库(如Access、Oracle等)却不支持Transact-SQL。SQL Server已经在市场中占据了主导地位,特别是随着SQL Server 版本的不断翻新,加上微软公司的强力支撑,SQL Server的主导地位将进一步获得增强。不管是数据库管理员仍是数据库应用程序开发人员,要想深刻领会和掌握数据库技术,必须认真学习Transact-SQL。除了拥有SQL语言全部的功能外,Transact-SQL还具有对SQL Server数据库独特的管理功能。数据库
1. 标识符express
在数据库编程中,要访问任何一个逻辑对象(如变量、过程、触发器等)都须要经过其名称来完成。逻辑对象的名称是利用合法的标识符来表示的,是在建立、定义对象时设置的,此后就能够经过名称来引用逻辑对象。编程
2. 数据类型安全
与其余编程语言同样,Transact-SQL语言也有本身的数据类型。数据类型在定义数据对象(如列、变量和参数等)时是必须的。自SQL Server 2008版本开始就新增了XML数据类型,以用于保存XML数据。Transact-SQL语言的其余数据类型与SQL的相同。架构
3. 函数编程语言
SQL Server 2008内置了大量的函数,如时间函数、统计函数、游标函数等,极大地方便程序员的使用。ide
4. 表达式函数
表达式是由表示常量、变量、函数等的标识符经过运算符链接而成的、具备实际计算意义的合法字符串。有的表达式不必定含有运算符,实际上单个的常量、变量等均可以视为一个表达式,它们每每不含有运算符。
5. 注释
Transact-SQL语言中有两种注释,一种是行单行注释,一种是多行注释。它们分别用符号“--”(连续的两个减号)和“/* */”来实现。
6. 关键字
关键字也称为保留字,是SQL Server预留做专门用途的一类标识符。例如,ADD、EXCEPT、PERCENT等都是保留关键字。用户定义的标识符不能与保留关键字重复。
标识符有两种类型:常规标识符和分隔标识符。
常规标识符在使用时不需将其分隔开,要符合标识符的格式规则。
这些规则就是,标识符中的首字符必须是英文字母、数字、_(下划线)、@、#或汉字,
首字符后面能够是字母、数字、下划线、@和$等字符,能够包含汉字。
标识符通常不能与SQL Server的关键字重复,
也不该以@@开头(由于系统全局变量的标识符是以@@开头),
不容许嵌入空格或其余特殊字符等。
分隔标识符是指包含在两个单引号(' ') 或者方括号([ ]) 内的字符串,这些字符串中能够包含空格。
在SQL Server中,全局变量是以@@开头,后跟相应的字符串,如@@VERSION等。若是想查看全局变量的值,可用SELECT语句或print语句来完成。
查看全局变量的值@@VERSION的值,相应的print语句以下:
print @@VERSION;
该语句执行后在笔者机器上输出以下结果:
Microsoft SQL Server 2014 - 12.0.4100.1 (X64)
Apr 20 2015 17:29:27
Copyright (c) Microsoft Corporation
Standard Edition (64-bit) on Windows NT 6.1 <X64> (Build 7601: Service Pack 1)
(1)定义局部变量
局部变量是由用户定义的,语法以下:
DECLARE @variable1 data_type[,variable2 data_type, …]
@variable1, @variable2,…为局部变量名,它们必须以单字符“@”开头;data_type为数据类型,它是能够是系统数据类型,也能够是用户定义的数据类型,具体选择什么样的类型要根据实际须要而定。有关数据类型的说明见第4章的相关内容。
【例6.1】定义一个用于存储姓名的局部变量。
DECLARE @name_str varchar(8);
【例6.2】同时定义三个分别用于存储学号、出生日期和平均成绩的局部变量。
DECLARE @no_str varchar(8), @birthday_str smalldatetime, @avgrade_num numeric(3,1);
(2)使用SET对局部变量赋初值
在定义局部变量之后,变量自动被赋以空值(NULL)。若是须要对已经定义的局部变量赋一个初值,可用SET语句来实现,其语法以下:
SET @variable = value;
@variable为局部变量名,value为新赋的值。
【例6.3】对上例定义的三个变量@no_str、@birthday_str和@avgrade_num分别赋初值'20170112'、'2000-2-5'和89.8。
这个赋值操做能够下三个SET语句来完成:
SET @no_str='20170112'; SET @birthday_str='2000-2-5'; SET @avgrade_num = 89.8;
注意,不能同时对多个变量进行赋值,这与同时对多个变量进行定义的状况不一样
【例子】下列的SET语句是错误的:
SET @no_str='20170112', @birthday_str='2000-2-5', @avgrade_num = 89.8; -- 错误
(3)使用SELECT对局部变量赋初值
SELECT是查询语句,利用该语句能够将查询的结果赋给相应的局部变量。若是查询返回的结果包含多个值,则将最后一个值赋给局部变量。
使用SELECT对局部变量赋初值的语法格式以下:
SELECT @variable1= value1[, @variable2= value2, …] FROM table_name [WHERE …]
【例6.4】 查询表student,将姓名为“刘洋”的学生的学号、出生日期和平均成绩分别赋给局部变量@no_str、@birthday_str和@avgrade_num。
该赋值操做用SELECT语句来实现则很是方便,其代码以下:
SELECT @no_str = s_no, @birthday_str = s_birthday, @avgrade_num = s_avgrade FROM student WHERE s_name = '刘洋';
【例6.5】先定义局部变量@s_no和@s_avgrade,而后对其赋值,最后利用这两个变量修改数据表student的相关信息。
USE MyDatabase GO -- 定义局部变量 DECLARE @s_no varchar(8), @s_avgrade numeric(3,1); -- 对局部变量赋值 SET @s_no='20170208'; SET @s_avgrade = 95.0; -- 使用局部变量 Update student SET s_avgrade = @s_avgrade WHERE s_no = @s_no;
字符串常量是由两个单引号来定义的,是包含在两个单引号内的字符序列。
这些字符包括字母数字字符(a-z、A-Z 和0-9)以及特殊字符,如感叹号(!)、at 符(@) 和数字号(#)等。
默认状况下,SQL Server 2014为字符串常量分配当前数据库的默认排序规则,
但也能够用COLLATE 子句为其指定排序规则。
【例子】下列都是合法字符串常量:
'China' '中国人民共和国'
若是字符串中包含一个嵌入的单引号,则须要在该单引号前再加上一个单引号,表示转义,这样才能定义包含单引号的字符串。
【例子】下列包含单引号的字符串都是合法的:
'AbC''Dd!' -- 表示字符串“AbC'Dd!” 'xx: 20%y%.'
有许多程序员习惯用双引号来定义字符串常量。但在默认状况下,SQL Server不容许使用这样的定义方式。
若是将QUOTED_IDENTIFIER 选项设置为OFF,则SQL Server同时支持运用双引号和单引号来定义字符串。
设置QUOTED_IDENTIFIER的方法用下列语句:
SET QUOTED_IDENTIFIER OFF;
在执行该语句后,QUOTED_IDENTIFIER 被设置为OFF。这时除了单引号之外,还能够用双引号来定义字符串。
【例子】下列定义的字符串都是合法的:
'China' '中国人民共和国' 'AbC''Dd!' -- 表示字符串“AbC'Dd!” 'xx: 20%y%.' "China" "中国人民共和国" "AbC''Dd!" -- 表示字符串“AbC''Dd!” "xx: 20%y%."
注意,当用双引号定义字符串时,若是该字符串中包含单引号,则不能在单引号前再加上另外一个单引号,不然将获得另外的一种字符串。
【例子】 'AbC''Dd!'定义的是字符串“AbC'Dd!”,而"AbC''Dd!"定义则是字符串“AbC''Dd!”。
SQL Server将空字符串解释为单个空格。
若是不须要用双引号来定义字符串,则只要将QUOTED_IDENTIFIER恢复为默认值ON便可。须要执行下列语句:
SET QUOTED_IDENTIFIER ON;
SQL Server 2014支持Unicode字符串。Unicode字符串是指按照Unicode标准来存储的字符串。但在形式上与普通字符串类似,不一样的是它前面有一个N 标识符(N 表明SQL-92 标准中的区域语言),且前缀N必须是大写字母。
【例子】 'China'是普通的字符串常量,而N'China'则是Unicode字符串常量。
整型常量也用得不少,它是不用引号括起来且不包含小数点的数字字符串。
【例子】 200七、-14等都是整型常量。
【例子】下面是定义整型常量及对其赋值的例子:
DECLARE @i integer SET @i = 99;
日期时间常量一般是用字符串常量来表示,
但前提是字符串常量可以隐式转换为日期时间型数据,
其格式为“yyyy-mm-dd hh:mm:ss.nnn”或“yyyy/mm/dd hh:mm:ss.nnn”,
其中yyyy表示年份,第一个mm表示月份,dd表示月份中的日期,
hh表示小时,第二个mm表示分钟,ss表示秒,nnn表示毫秒。
若是“yyyy-mm-dd”缺省,则日期部分默认为1900年01月01日;
若是“hh:mm:ss.nnn”缺省,则时间部分默认为00时00分00.000秒。
【例子】下面是一些将日期时间型常量赋给日期时间型变量的例子:
DECLARE @dt datetime SET @dt = '2017-01-03 21:55:56.890' --2017年01月03日21时55分56.890秒 SET @dt = '2017/12/03' --2017年01月03日0时0分0秒 SET @dt = '2017-01-03' --2017年01月03日0时0分0秒 SET @dt = '21:55:56.890' --1900年01月01日21时55分56.890秒
二进制常量是用前缀为0x的十六进制数字的字符串来表示,但这些字符串不用须要使用单引号括起。
【例子】下列是将二进制常量赋给二进制变量的例子:
DECLARE @bi binary(50) SET @bi = 0xAE SET @bi = 0x12Ef SET @bi = 0x69048AEFDD010E SET @bi = 0x0
数值型常量包括三种类型:decimal型常量、float型常量和real型常量。
decimal型常量是包含小数点的数字字符串,但这些字符串不需单引号括起来(定点表示)。
【例子】下面是decimal型常量的例子:
3.14159
-1.0
float型常量和real型常量都是使用科学记数法来表示(浮点表示)。
【例子】
101.5E5
-0.5E-2
位常量使用数字0或1来表示,而且不用单引号括起来。若是使用一个大于1的数字,则该数字将转换为1。
【例子】
DECLARE @b bit SET @b = 0;
货币常量是前缀为可选的小数点和可选的货币符号的数字字符串,且不用单引号括起来。SQL Server 2008不强制采用任何种类的分组规则,例如在表明货币的字符串中不容许每隔三个数字用一个逗号隔开。
【例子】 如下是货币常量的例子:
$20000.2 -- 而$20,000.2是错误的货币常量 $200
这是指uniqueidentifier类型的常量,它使用字符或二进制字符串格式来指定。
【例子】
'6F9619FF-8B86-D011-B42D-00C04FC964FF’ 0xff19966f868b11d0b42d00c04fc964ff
以上介绍的八种类型的常量主要运用于对变量和字段赋值、构造表达式、构造子句等。在从此的介绍中将进一步领会到它的使用方法。
SQL Server 2014中,字符串型数据能够由汉字、英文字母、数字等符号组成。根据编码方式的不一样,字符串型又分为Unicode字符串型和非Unicode字符串型。
Unicode字符串型数据是指对全部字符均采用双字(16bit)节统一编码的一类数据;
非Unicode字符串型数据则是指对不一样国家或地区采用不一样编码长度的一类数据,例如英文字母使用一个字节(8bit)进行编码,汉字则使用两个字节(16bit)进行编码。
SQL Server 2014主要支持的字符串型数据类型如表5.2所示。
按照不一样的精确程度,将数值型数据类型分为两种,一种是精确型,另外一种是近似型。
精确型数据是指在计算机中能够精确存储的数据。这种数据类型包括各类整型数据类型、定点型数据类型等,
表5.3列出了SQL Server 2014支持的精确型数据类型。
近似型主要是指浮点型float和real。这种类型的数据在内存中不必定可以精确表示,可能会存在一些微小的偏差。
日期时间型,包括两种:datetime和smalldatetiime。日期时间型既能够用于存储时间型数据,也能够用于存储日期型数据。
自从SQL Server 2012开始,新增了4种与日期时间相关的新数据类型:datetime二、dateoffset、date和time。
货币型是用来存储货币值数据,它固定精确到小数点后四位,至关于numeric(m,n)类型的特例(n=4)。SQL Server支持两种货币型。
二进制型数据类型包括三种:binary(n)、varbinary(n)和image。其做用和含义说明如表5.7所示。
SQL Server 2014还支持如下的数据类型:
sql_variant:一种通用数据类型,存储除了text、ntext、image、timestamp和它自身之外的其余类型的数据,其最大存储量为8000字节。
timestamp:时间戳类型,每次更新时会自动更新该类型的数据。做用跟邮局的邮戳相似,一般用于证实某一项活动(操做)是在某一时刻完成的。
uniqueidentitier:全局惟一标识符(GUID),其值能够从Newsequentialid()函数得到,这个函数返回的值对全部计算机来讲是惟一的。
xml:做为一种存储格式,xml类型具备SQL Server中其余类型的全部功能,还能够添加子树、删除子树和更新标量值等,最多存储2GB数据。
table:表类型,用于返回表值函数的结果集,其大小取决于表中的列数和行数。
hierarchyid:层次类型,包含对层次结构中位置的引用,占用空间为1至892字节+2字节的额外开销。
cursor:游标类型,包含对游标的引用,只能用做变量或存储过程参数,不能用于Create Table语句中。
根据实际须要,用户可利用已有的标准数据类型来定义本身的数据类型,这种类型称为自定义数据类型。自定义数据类型可由CREATE TYPE语句来定义。
【例子】 用户能够用下列语句建立表示地址的数据类型——address:
CREATE TYPE address FROM varchar(350) NOT NULL;
执行上述语句后,就生成了名为address的数据类型,同时增长了约束条件——NOT NULL。就能够用address去定义字段和变量。该数据类型就是与varchar(350)同等,只不过它增长了一个非空约束条件。
再也不须要数据类型address,能够用下列语句将之删除:
DROP TYPE address;
但在删除以前,先删除全部引用该数据类型的数据库对象。
在Transact-SQL程序中经常使用的系统内置函数能够分为四种类型:字符串处理函数、聚合函数、时间函数和数学函数。
(1)ASCII函数
该函数的语法以下:
ASCII ( character_expression )
character_expression为char或varchar类型的字符串表达式。其做用是以int类型返回字符串表达式character_expression中第一个字符的ASCII值。
【例子】 ASCII ('Abcd')返回65,ASCII ('abcd')返回97等('A'和'a'的ASCII值分别为65和97)。
(2)SUBSTRING函数
该函数的语法以下:
SUBSTRING( expression ,start , length )
该函数的做用是返回给定字符expression中的一个子串,该子串是从位置start开始、长度为length的字符串。其中,expression能够是字符串、二进制字符串、文本、图像、列或包含列的表达式,但不能使用包含聚合函数的表达式,start , length都是整型数据。
【例子】 SU BSTRING('abcdef',2, 4)返回'bcde',SUBSTRING('abcdef',2, 1)返回'b'等。
(3)LEFT函数
该函数的语法以下:
LEFT(character_expression, integer_expression)
其做用是返回字符串character_expression中从左边开始的integer_expression个字符。
【例子】 打印学生的姓氏,能够用下列的语句来实现(不考虑复姓):
SELECT LEFT(s_name,1) FROM student
(4)REPLACE函数
该函数的语法以下:
REPLACE(string_expression1 , string_expression2, string_expression3)
其做用是用第三个表达式string_expression3替换第一个字符串表达式string_expression1中出现的全部第二个指定字符串表达式string_expression2的匹配项,并返回替换后的字符串表达式。
【例子】 REPLACE('abcdefghicde','cd','China')将返回'abChinaefghiChinae'。
(1)COUNT函数
该函数用于返回组中的项数,其语法以下:
COUNT({[[ALL|DISTINCT] expression]|*})
该函数有三种调用形式:
COUNT(*):返回组中的行数,包括NULL值和重复行。
COUNT(ALL expression):对组中的每一行都计算expression并返回非NULL值的个数,式中的ALL能够省略。
COUNT(DISTINCT expression):对组中的每一行都计算expression并返回惟一非空值的个数。
(2)AVG函数
该函数返回组中各值的平均值,NULL被忽略。其语法以下:
AVG( [ ALL | DISTINCT ] expression )
【例子】 求女学生的平均成绩,能够用下列的语句来完成:
SELECT AVG(s_avgrade) FROM student WHERE s_sex = '女'
(3)MAX函数
该函数的语法格式以下:
MAX([ ALL | DISTINCT ] expression )
它返回表达式的最大值
(4)MIN函数
该函数的语法格式以下:
MIN([ ALL | DISTINCT ] expression )
它返回表达式的最小值。
(5)SUM函数
该函数的语法格式以下:
SUM([ ALL | DISTINCT ] expression )
当选择ALL(默认)时,它返回表达式expression中全部值的和;当选择DISTINCT时,它返回仅非重复值的和。NULL值被忽略。
经常使用的日期时间函数说明如表6.6所示。
数学函数用于对数值型字段和表达式进行处理,经常使用的函数如表6.7所示。
(1)CAST函数
该函数用于将一种数据类型的表达式显式转换为另外一种数据类型的表达式。其语法以下:
CAST(expression AS data_type [(length )])
即将表达式expression的值转换为data_type类型的数据,并返回转化后的数据类型。常使用的类型转换主要包括如下几种:
数值型 <-> 字符串型
字符串型 <-> 日期时间型
【例子】
CAST(10.6496 AS int) -- 将常量10.6496转化int类型数据,结果变为10 CAST('abc' AS varchar(5)) -- 将常量'abc'转化为varchar(5)类型 CAST('100' AS int) -- 将字符串常量'100'转化为数值常量100 CAST(100 AS varchar(5)) -- 将数值常量100转化字符串常量'100' CAST('2017/12/12' AS datetime) -- 将字符串常量'2017/12/12'转化为时间常量12 12 2017 CAST(GETDATE() AS VARCHAR(20)) -- 将当前系统时间转化为字符串常量
查询成绩在70到80(不含80)分之间的学生,能够用下列的语句实现:
SELECT * FROM student WHERE CAST(s_avgrade AS varchar(10)) like '7%'
该语句首先将成绩转换为字符串,而后将70到80之间的分数看做是以7开头的字符串,最后经过利用模糊查询来实现该查询功能。它等价于下列的SELECT语句:
SELECT * FROM student WHERE s_avgrade >= 70 and s_avgrade < 80
(2)CONVERT函数
该函数与CAST函数的功能类似,都是用于将一种数据类型的表达式显式转换为另外一种数据类型的表达式,但CONVERT函数的功能更强一些。其语法以下:
CONVERT( data_type [ ( length ) ] , expression [ , style ] )
与CAST函数不一样的是,在CONVERT函数中被转换的表达式靠近函数式的右边,而在CONVERT函数中则靠近左边。
【例子】下列语句中使用了CONVERT函数,该语句与上述查询语句等价:
SELECT * FROM student WHERE CONVERT(varchar(10), s_avgrade) like '7%'
用户自定义函数由CREATE FUNCTION语句来定义,分为如下几种类型。
(1)标量函数的定义和引用
标量函数是指返回值为标量值的函数。其语法格式以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ][ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS return_data_type [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN scalar_expression END [ ; ] <function_option>::= { [ ENCRYPTION ] | [ SCHEMABINDING ] | [ RETURNS NULL ON NULL INPUT | CALLED ON NULL INPUT ] | [ EXECUTE_AS_Clause ] }
其中:
schema_name为架构名称。
function_name为用户定义的函数名,它必须符合SQL Server标识符的规则,在架构schema_name中是惟一的。
@parameter_name为用户定义的形式参数的名称,能够声明一个或者多个参数,parameter_data_type为参数的类型。
function_body表示函数体,即Transact-SQL语句块,是函数的主体部分。
在<function_option>项中,ENCRYPTION用于指示数据库引擎对包含CREATE FUNCTION语句文本的目录视图列进行加密,以防止将函数做为SQL Server复制的一部分发布;SCHEMABINDING指定将函数绑定到其引用的数据库对象,若是其余架构绑定对象也在引用该函数,此条件将防止对其进行更改。
若是定义了 default 值,则无需指定此参数的值便可执行函数。
EXECUTE AS 子句用于指定用于执行用户定义函数的安全上下文。
【例6.15】 构造一个函数,使之可以根据学号从表SC中计算学生已选课程的平均成绩。
USE MyDatabase; GO IF OBJECT_ID(N'dbo.get_avgrade', N'FN') IS NOT NULL DROP FUNCTION dbo.get_avgrade; -- 若是已存在名为get_avgrade的函数则将其删除 GO CREATE FUNCTION dbo.get_avgrade(@s_no varchar(8)) RETURNS float AS BEGIN DECLARE @value float; SELECT @value = AVG(c_grade) FROM sc WHERE s_no = @s_no RETURN @value; END
对于用户自定义函数,其调用方法与变量的引用方式同样,主要有如下几种调用格式。
①在SELECT或者PRINT语句中调用函数
【例子】 能够用下列语句调用自定义函数get_avgrade:
DECLARE @SS varchar(8); SET @SS = '20170202' SELECT dbo.get_avgrade(@SS) --或者, SELECT dbo.get_avgrade('20170202') --若是仅仅用于打印输出,能够将上述的关键字SELECT改成PRINT,也有一样的效果。
② 利用SET语句执行函数
在SET语句中,函数被看成一个表达式进行计算,而后将返回值赋给指定的变量。
【例子】
DECLARE @V float SET @V = dbo.get_avgrade('20170202')
(2)内联表值函数
内联表值函数返回的结果是一张数据表,而不是一个标量值。其语法以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS TABLE [ WITH <function_option> [ ,...n ] ] [ AS ] RETURN [ ( ] select_stmt [ ) ] [ ; ]
能够看到,该函数返回结果是TABLE类型数据(是一张表),且没有函数主体(BEGIN…END部分),而标量函数返回的是一个标量值,有本身的函数主体。
【例子】 定义内联表值函数。该函数的做用是按学号查询学生的学号、姓名和系别,其输入参数是学号,返回结果是由学号、姓名和系别构成的表。
USE MyDatabase; GO IF OBJECT_ID(N'dbo.get_SND', N'IF') IS NOT NULL DROP FUNCTION dbo.get_SND; GO CREATE FUNCTION dbo.get_SND(@s_no varchar(8)) RETURNS TABLE AS RETURN ( SELECT s_no, s_name, s_dept FROM student WHERE s_no = @s_no );
因为内联表值函数返回结果是一张表,因此对其调用必须按照对表的查询方式进行,其调用方法与标量函数的调用方法彻底不一样。
【例子】 如下是调用函数get_SND的一条SELECT语句,在此函数get_SND是被看成一张表来使用的:
SELECT * FROM dbo.get_SND('20170203')
内联表值函数返回的结果是一张“数据表”,而其自己并不保存数据。在这个意义上,内联表值函数与第8章介绍的视图是同样的,并且也能够像对视图那样对其进行查询操做。其优势是它能够带参数,而视图不能带参数,但它不具有视图的所有功能。能够这样简要理解:内联表值函数是带参数的“视图”。
(3)多语句表值函数
多语句表值函数返回结果也是一张表,但与内联表值函数不一样的是:在内联表值函数中,TABLE返回值是经过单个SELECT语句定义的,内联函数没有关联的返回变量。
在多语句表值函数中,@return_variable是TABLE类型的返回变量,用于存储和汇总应做为函数值返回的行。
多语句表值函数返回结果的原理是,先定义一个表变量,而后经过函数体中的语句实现向该表变量插入有关数据,最后将这个表变量做为结果返回。
多语句表值函数的语法以下:
CREATE FUNCTION [ schema_name. ] function_name ( [ { @parameter_name [ AS ] [ type_schema_name. ] parameter_data_type [ = default ] } [ ,...n ] ] ) RETURNS @return_variable TABLE < table_type_definition > [ WITH <function_option> [ ,...n ] ] [ AS ] BEGIN function_body RETURN END [ ; ]
@return_variable为TABLE类型变量,用于存放函数返回的表。
多语句表值函数与标量函数都有函数的主体部分(function_body),它是由一系列定义函数值的Transact-SQL语句组成。在多语句表值函数中,function_body是一系列用于填充TABLE返回变量@return_variable的Transact-SQL 语句;在标量函数中,function_body是一系列用于计算标量值的Transact-SQL 语句。
【例6.16】 下例是一个多语句表值函数,其做用是按学号查询学生的一些基本信息。这些信息包括学号、姓名、专业、系别和平均成绩,其平均成绩是计算列,它由学生已选修的课程及课程成绩来决定。学生选修课程记录于表SC中。
该函数名为get_stu_info,带一个参数,其定义代码以下:
USE MyDatabase; GO IF OBJECT_ID (N'dbo.get_stu_info', N'TF') IS NOT NULL DROP FUNCTION dbo.get_stu_info; GO CREATE FUNCTION dbo.get_stu_info(@no char(8)) RETURNS @stu_info TABLE -- 定义表变量 ( s_no char(8), s_name char(8), s_speciality varchar(50), s_dept varchar(50), s_avgrade numeric(3,1) ) AS BEGIN INSERT @stu_info -- 插入查询信息 SELECT s_no,s_name,s_speciality,s_dept,s_avgrade=( /*从表SC中生成计算列s_avgrade */ SELECT AVG(c_grade) FROM SC WHERE SC.s_no = student.s_no ) FROM student WHERE s_no=@no RETURN END
多语句表值函数的调用与内联表值函数的调用方法同样。
【例子】要查询学号为'20170201'的学生信息,能够按照下列方式调用函数get_stu_info:
SELECT * FROM dbo.get_stu_info('20170201');
用户自定义函数的删除实际上在上述介绍的例子中已经接触过了,即用DROP FUNCTION来实现对函数的删除。
【例子】 删除函数get_stu_info可使用下列语句来完成:
DROP FUNCTION dbo.get_stu_info;
运算符是用来指定要在一个或多个表达式中执行操做的一种符号。在SQL Server 2014中,使用的运算符包括算术运算符、逻辑运算符、赋值运算符、字符串串联运算符、按位运算符、一元运算符和比较运算符等。
1. 算术运算符
算术运算符加(+)、减(-)、乘(*)、除(/)和取模(%)等五种运算符。它们用于执行对两个表达式的运算,这两个表达式的返回值必须是数值数据类型,包括货币型。
加(+) 和减(-) 运算符还能够用于对日期时间类型值的算术运算。
2. 逻辑运算符
逻辑运算符用于对某些条件进行测试,返回值为TRUE或FALSE。逻辑运算符包括ALL、AND、ANY、BETWEEN、EXISTS、IN、LIKE、NOT、OR、SOME等,其含义说明如表6.2所示,其中有部分运算符已在第5章中介绍过。
3. 赋值运算符
赋值运算符就是等号“=”,它是Transact-SQL中惟一的赋值运算符。例如,上节对局部变量的赋值操做实际上已经使用了赋值运算符。
除了用做赋值操做之外,赋值运算符还能够用于创建字段标题和定义字段值的表达式之间的关系。
【例子】 下列语句建立了两个字段,其中第一个字段的列标题为“中国”,全部字段值均为“China”;第二个字段的列标题为“姓名”,该字段的字段值来自表student中的s_name字段值。
SELECT 中国= 'China', 姓名= s_name FROM student
执行结果以下:
中国 姓名
--------------------------
China 刘洋
China 王晓珂
China 王伟志
China 岳志强
China 贾簿
China 李思思
China 蒙恬
China 张宇
4. 字符串链接运算符
在SQL Server中,字符串链接运算符为加号“+”,表示要将两个字符串链接起来而造成一个新的字符串。该运算符能够操做的字符串类型包括char、varchar、text以及nchar、nvarchar、ntext等。
【例子】
'abc'+'defg' -- 结果为'abcdefg' ‘abc’ + ‘’ + ‘def’ -- 结果为‘abcdef’(默认),当兼容级别设置为65时结果为 'abc def'
针对字符串的操做有不少种,如取子串等。但在SQL Server中仅有字符串链接操做由运算符“+”来完成,而全部其余的字符串操做都使用字符串函数来进行处理。
5. 位运算符
位运算符是表示在两个操做数之间执行按位进行运算的符号,操做数必须为整型数据类型之一,如bit、tinyint、smallint、int、bigint等,还能够是二进制数据类型(image 数据类型除外)。表6.3列出了位运算符及其含义。
6. 比较运算符
比较运算符用于测试两个表达式的值之间的关系,这种关系是指等于、大于、小于、大于等于、小于等于、不等于、不小于、不大于等。比较运算符几乎适用于全部的表达式(除了text、ntext 或image 数据类型的表达式外)。表6.4列出了Transact-SQL 支持的比较运算符。
7. 运算符的优先级
运算符执行顺序的不一样会致使不一样的运算结果,因此正确地理解运算符的优先级是必要的。图6.1给出了运算符优优先级的示意图,其中从上到下运算符的优先级是由高到低,同一级中运算符的优先级是按照它们在表达式中的顺序从左到右依次下降。
注释是Transact-SQL程序代码中不被执行的文本部分,其做用是说明程序各模块的功能和设计思想,以方便程序的修改和维护。
注释有两种方法,一种是用“--”(紧连的两个减号)来注释,另外一种是用“/**/”来注释,它们都称为注释符。其中:
• --:用于注释一行代码,被注释的部分是从注释符“--”开始一直到其所在行末尾的部分。
• /* */:用于注释多行代码,被注释的部分包含在两个星号的中间。
【例子】 下面一段代码中同时使用了这两种注释:
USE MyDatabase; -- 使用数据库MyDatabase GO /* 该程序用于查询成绩及格的学生信息,包括学生姓名、性别、平均成绩。 程序编写者:xxx 程序编写时间:2017年12月31日 */ SELECT s_name, s_sex, s_avgrade --姓名、性别、平均成绩 FROM student --在表中查询 GO