第7章T-SQL语言基础7.1注释在SQLServer中,可以使用两种类型的注释字符:一种是ANSI标准的注释符“--”,它用于单行注释;另一种是与C语言相同的程序注释符号,即“/**/”“/*”用于注释文字的开头,。“*/”用于注释文字的结尾。例7-1使用两种注释类型的例子。程序清单如下:USEtestGO--Firstlineofamultiple-linecomment.--Secondlineofamultiple-linecomment.SELECT*FROMsGO/*注释语句的第一行.注释语句的第二行.*/SELECT*FROMscGO--在T-SQL语言调试过程中使用注释语句。7.2变量T-SQL语言中有两种形式的变量,一种是用户自己定义的局部变量,另外一种是系统提供的全局变量。1.局部变量局部变量的作用范围仅限制在程序内部。局部变量被引用时要在其名称前加上标志“@”,而且必须先用DECLARE命令定义后才可以使用。定义局部变量的语法形式如下:DECLAER{@local_variabledata_type}[…n]其中,参数@local_variable用于指定局部变量的名称,参数data_type用于设置局部变量的数据类型及其大小.data_type可以是任何由系统提供的或用户定义的数据类型。但是,局部变量不能是text,ntext或image数据类型。使用DECLARE命令声明并创建局部变量之后,会将其初始值设为NULL,如果想要设定局部变量的值,必须使用SELECT命令或者SET命令。其语法形式为:SET{@local_variable=expression}或者SELECT{@local_variable=expression}[,...n]其中,参数@local_variable是给其赋值并声明的局部变量,参数expression是任何有效的SQLServer表达式。例7-2创建一个@myvar变量,然后将一个字符串值放在变量中,最后输出@myvar变量的值。程序清单如下:DECLARE@myvarchar(20)select@myvar='Thisisatest'SELECT@myvarGO
22
例7-3通过查询给变量赋值。程序清单如下:USEtestGODECLARE@rowsintSET@rows=(SELECTCOUNT(*)FROMsc)2.全局变量除了局部变量之外,SQLServer系统本身还提供了一些全局变量。全局变量是SQLServer系统内部使用的变量,其作用范围并不仅仅局限于某一程序,而是任何程序均可以随时调用。全局变量通常存储一些SQLServer的配置设定值和统计数据。用户可以在程序中用全局变量来测试系统的设定值或者是T-SQL命令执行后的状态值。在使用全局变量时应该注意以下几点:(1)全局变量不是由用户的程序定义的,它们是在服务器级定义的。(2)用户只能使用预先定义的全局变量。(3)引用全局变量时,必须以标记符“@@”开头。(4)局部变量的名称不能与全局变量的名称相同,否则会在应用程序中出现不可预测的结果。例7-4显示到当前日期和时间为止试图登录SQLServer的次数。程序清单如下:SELECTGETDATE()AS'当前的时期和时间',@@CONNECTIONSAS'试图登录的次数'7.3运算符在SQLServer2005中,运算符主要有以下六大类:算术运算符、赋值运算符、位运算符、比较运算符、逻辑运算符和字符串串联运算符。1.算术运算符.算术运算符可以在两个表达式上执行数学运算,这两个表达式可以是数字数据类型分类的任何数据类型。算术运算符包括加(+)、减(-)、乘(*)、除(/)和取模(%)。2.赋值运算符.T-SQL中只有一个赋值运算符,即(=)。赋值运算符使我们能够将数据值指派给特定的对象。另外,还可以使用赋值运算符在列标题和为列定义值的表达式之间建立关系。3.位运算符.位运算符使我们能够在整型数据或者二进制数据(image数据类型除外)之间执行位操作。此外,在位运算符左右两侧的操作数不能同时是二进制数据。4.比较运算符.比较运算符亦称为关系运算符,用于比较两个表达式的大小或是否相同,其比较的结果是布尔值,即TRUE(表示表达式的结果为真)、FALSE(表示表达式的结果为假)以及UNKNOWN。除了text,ntext或image数据类型的表达式外,比较运算符可以用于所有的表达式。5.逻辑运算符.逻辑运算符可以把多个逻辑表达式连接起来。逻辑运算符包括AND、和NOT等运算符。OR逻辑运算符和比较运算符一样,返回带有TRUE或FALSE值的布尔数据类型。三个运算符的优先级别为:NOT,AND,OR。6.字符串串联运算符.字符串串联运算符允许通过加号(+)进行字符串串联,这个加号即被称为字符串串联运算
23
符。例如对于语句SELECT’abc’+’def’,其结果为abcdef。在SQLServer2005中,运算符的优先等级从高到低如下所示,如果优先等级相同,则按照从左到右的顺序进行运算。(1)括号:;()(2)乘、除、求模运算符:*,/,%;(3)加减运算符:+,-;(4)比较运算符:=,>,<,>=,<=,<>,!=,!>,!<;(5)位运算符:^,&;,|;(6)逻辑运算符:NOT;(7)逻辑运算符:AND;(8)逻辑运算符:OR。7.4函数在T-SQL语言中,函数被用来执行一些特殊的运算以支持SQLServer的标准命令。SQLServer包含多种不同的函数用以完成各种工作,每一个函数都有一个名称,在名称之后有一对小括号,如:gettime()。大部分的函数在小括号中需要一个或者多个参数。1、字符串函数、例7-5使用LTRIM函数删除字符变量中的起始空格。程序清单如下:DECLARE@string_to_trimvarchar(60)SET@string_to_trim='Fivespacesareatthebeginningofthisstring.'SELECT'Hereisthestringwithouttheleadingspaces:'+LTRIM(@string_to_trim)2、日期和时间函数、日期和时间函数用于对日期和时间数据进行各种不同的处理和运算,并返回一个字符串、数字值或日期和时间值。与其他函数一样,可以在SELECT语句的SELECT和WHERE子句以及表达式中使用日期和时间函数。例7-6从GETDATE函数返回的日期中提取月份名。程序清单如下:SELECTDATENAME(month,getdate())AS'MonthName'3、数学函数、数学函数用于对数字表达式进行数学运算并返回运算结果。例7-7selectround(rand()*100,0.5)4、系统函数、系统函数用于返回有关SQLServer系统、用户、数据库和数据库对象的信息。系统函数可以让用户在得到信息后,使用条件语句,根据返回的信息进行不同的操作。例7-8返回服务器的主机名称程序清单如下:SELECThost_name()7.5流程控制语句流程控制语句是指那些用来控制程序执行和流程分支的语句,在SQLServer2005中,流程控制语句主要用来控制SQL语句、语句块或者存储过程的执行流程。1.IF…ELSE语句IF…ELSE语句是条件判断语句,其中,ELSE子句是可选的,最简单的IF语句没有ELSE
24
子句部分。IF…ELSE语句用来判断当某一条件成立时执行某段程序,条件不成立时执行另一段程序。SQLServer允许嵌套使用IF…ELSE语句,而且嵌套层数没有限制。IF…ELSE语句的语法形式为:IFBoolean_expression{sql_statement|statement_block}[ELSE{sql_statement|statement_block}]例7-9如果李四的平均成绩为60分以上,显示其成绩情况,否则显示文本:成绩状态不理想。declare@avgsintselect@avgs=avg(grade)froms,scwheres.sno=sc.snoandsname='李四'if(@avgs>=60)selects.sno,sname,cno,gradefroms,scwheres.sno=sc.snoandsname='李四'elseprint'成绩不理想'2.BEGIN…END语句BEGIN…END语句能够将多个T-SQL语句组合成一个语句块,并将它们视为一个单元处理。在条件语句和循环等控制流程语句中,当符合特定条件便要执行两个或者多个语句时,就需要使用BEGIN…END语句。BEGIN…END语句的语法形式为:BEGIN{sql_statement|statement_block}END3.GO语句Go语句是批的结束语句。批是一起提交并作为一个组执行的若干SQL语句。例7-10用Go语句作为批的结束语句。程序清单如下:USEadventureworksGODECLARE@MyMsgVARCHAR(50)SELECT@MyMsg='Hello,World.'GO--@MyMsg在Go语句后失效。4.CASE语句CASE语句可以计算多个条件式,并将其中一个符合条件的结果表达式返回。CASE语句按照使用形式的不同,可以分为简单CASE语句和搜索CASE语句。简单CASE表达式:CASE表达式WHEN表达式THEN表达式
25
WHEN表达式THEN表达式[...n][ELSE表达式]END例7-11根据sdept的数据显示其详细内容usetestgodeclare@deptvarchar(50)select@dept=casesdeptwhen'cs'then'计算机系'when'info'then'信息系'when'ma'then'数学系'else'出错'endfromswheresno='001'--显示其值select@deptas系部搜索CASE:CASEWHEN布尔表达式THEN表达式WHEN布尔表达式THEN表达式[...n][ELSE表达式]END例7-12使用搜索CASE,根据成绩的范围将显示其对应系的文本usetestgodeclare@scorechar(1)select@score=casewhengrade>=90andgrade<=100then'A'whengrade>=80andgrade<90then'B'whengrade>=70andgrade<80then'C'whengrade>=60andgrade<70then'D'else'E'endfromscwherecno='100'andsno='001'select@score5.WHILE…CONTINUE…BREAK语句WHILE…CONTINUE…BREAK语句用于设置重复执行SQL语句或语句块的条件。只要指定的条件为真,就重复执行语句。其中,CONTINUE语句可以使程序跳过CONTINUE语句后面的语句,回到WHILE循环的第一行命令。BREAK语句则使程序完全跳出循环,结束
26
WHILE语句的执行。其语法形式为:WHILEBoolean_expression{sql_statement|statement_block}[BREAK]{sql_statement|statement_block}[CONTINUE]例7-13计算1到10之间的奇数之和declare@itinyint,@sumintset@sum=0set@i=0while@i>=0beginif(@i>=10)beginselect'总和'=@sumbreakendelsebeginset@i=@i+1if(@i%2)=0continueelseset@sum=@sum+@iendend6.GOTO语句GOTO语句可以使程序直接跳到指定的标有标识符的位置处继续执行,而位于GOTO语句和标识符之间的程序将不会被执行。GOTO语句和标识符可以用在语句块、批处理和存储过程中,标识符可以为数字与字符的组合,但必须以“:”结尾。如:‘a1:’。在GOTO语句行,标识符后面不用跟“:”。GOTO语句的语法形式为:GOTOlabel……label:例7-57利用GOTO语句求出从1加到5的总和。程序清单如下:declare@sumint,@countintselect@sum=0,@count=1label_1:select@sum=@sum+@countselect@count=@count+1if@count<=5
27
gotolabel_1select@count@sum7.WAITFOR语句WAITFOR语句用于暂时停止执行SQL语句、语句块或者存储过程等,直到所设定的时间已过或者所设定的时间已到才继续执行。WAITFOR语句的语法形式为:WAITFOR{DELAY'time'|TIME'time'}其中,DELAY用于指定时间间隔,TIME用于指定某一时刻,其数据类型为datetime,格式为‘hh:mm:ss’。例7-14使用WAITFORTIME语句,以便在晚上10:20执行存储过程update_all_stats。程序清单如下:BEGINWAITFORTIME'22:20'EXECUTEupdate_all_statsEND8.RETURN语句RETURN语句用于无条件地终止一个查询、存储过程或者批处理,此时位于RETURN语句之后的程序将不会被执行。RETURN语句的语法形式为:RETURN[integer_expression]其中,参数integer_expression为返回的整型值。存储过程可以给调用过程或应用程序返回整型值。例7-15显示如果在执行findjobs时没有给出用户名作为参数,RETURN则将一条消息发送到用户的屏幕上然后从过程中退出。如果给出用户名,将从适当的系统表中检索由该用户在当前数据库内创建的所有对象名。程序清单如下:CREATEPROCEDUREfindjobs@nmsysname=NULLASIF@nmISNULLBEGINPRINT'Youmustgiveausername'RETURNENDELSEBEGINSELECTo.name,o.id,o.uidFROMsysobjectsoINNERJOINmaster..sysloginslONo.uid=l.sidWHEREl.name=@nmEND
28