3.7.6 流程控制

3.7.6 流程控制

通过使用流程控制语句,用户可以完成功能较为复杂的操作,并使程序可以获得更好的逻辑性和结构性。Transact-SQL提供了称为流程控制的关键字,可以用于控制程序执行的流程,主要的流程控制语句有:BEGIN...END、IF...ELSE、CASE、WHILE、WAITFOR、RETURN等。

1)BEGIN...END语句

BEGIN...END语句可以将多个Transact-SQL语句组合成一个语句块,并将它们视为一个单元处理,其基本格式如下:

说明:

BEGIN和END是关键字,分别表示语句块的开始和结束,必须成对使用;

sql_statement|statement_block:任何有效的Transact-SQL语句或语句组;

BEGIN...END语句块可以嵌套,嵌套层数没有限制。

BEGIN...END通常包含在其他流程控制语句中,用来完成不同流程中的代码段,例如,IF子句、ELSE子句或WHILE循环如果需要包含语句块,需用到BEGIN...END语句块。

2)IF...ELSE语句

IF...ELSE语句用于在执行一组代码之前进行条件判断,根据判断的结果执行不同的代码,常用于批处理或存储过程等。IF...ELSE语句对IF后的布尔表达式进行判断,如果布尔表达式返回TRUE,则执行IF关键字及其条件之后的语句或语句块;如果布尔表达式返回FALSE,则执行ELSE后面的语句或语句块。其基本格式如下:

说明:

boolean_expression:返回TRUE或FALSE的表达式,如果boolean_expression中含有SELECT语句,则必须用圆括号将SELECT语句括起来;

sql_statement|statement_block:任何有效的Transact-SQL语句或用BEGIN...END语句定义的语句块,除非使用语句块,否则IF或ELSE条件只能影响一个Transact-SQL语句的性能;

IF...ELSE语句可以嵌套使用,且嵌套层数没有限制。不过建议嵌套层数不要太多,否则会降低程序的可读性。

【例3.82】 从学生选课表SC中求出学号为“201818103”同学的平均成绩,如果该生平均成绩大于或等于60分,则输出“Congratulate!Pass!”信息,否则输出“Sorry!No Pass!”。

3)CASE语句

CASE语句是多条件分支语句,相比IF...ELSE,CASE语句进行分支流程控制可以使代码更加清晰,易于理解。CASE语句通过计算条件列表,返回多个可能的结果表达式之一,因此CASE可用于允许使用有效表达式的任意语句或子句。例如,可以在SELECT、UPDATE、DELETE等语句以及select_list、WHERE、ORDER BY和HAVING等子句中使用CASE。

按照使用形式的不同,CASE语句分为简单CASE和搜索CASE。

(1)简单CASE

简单CASE将表达式与一组简单的表达式进行比较以确定结果,其基本格式如下:

说明:

input_expression、when_expression和result_expression:任何有效的表达式,input_expression及每个when_expression的数据类型必须相同或必须是隐式转换的数据类型;result_expression是当input_expression=when_expression的计算结果为TRUE时,返回的表达式;

else_result_expression:比较运算计算结果不为TRUE时返回的表达式;

该语句的执行过程是:将input_expression与每个WHEN关键字后的when_expression 进行比较,如果相等,则返回相应的THEN关键字后的result_expression,然后跳出CASE语句;否则,返回ELSE关键字后的else_result_expression;

ELSE子句是可选项。当CASE语句中不包含ELSE子句,且input_expression与每个when_expression都不相等时,CASE语句将返回NULL。

【例3.83】 从学生表Student中,选取每个学生的学号和性别输出,若性别为“男”,则输出“M”;若性别为“女”,则输出“F”;否则输出“性别未知”。

可能的查询结果为:

(2)搜索CASE

搜索CASE语句计算一组布尔表达式以确定返回的结果,其基本格式如下:

说明:

boolean_expression:任何有效的布尔表达式;

该语句的执行过程是:首先测试第一个WHEN关键字后的boolean_expression的值,如果其值为TRUE,则返回相应的THEN关键字后的result_expression;否则测试下一个WHEN关键字后的boolean_expression。如果所有WHEN关键字后的boolean_expression的值都为FALSE,则返回ELSE关键字后的else_result_expression,如果没有ELSE子句,则返回NULL。

【例3.84】 根据百分制成绩输出等级制成绩。

可能的查询结果为:

【例3.85】 在学生选课表SC中,统计每门课程选修的男女生数量。

可能的查询结果为:

【例3.86】 为使学生的成绩更符合正态分布且方差尽可能小,现假设需修改学生选课表SC中的数据,将高于90分的成绩降低5%,将成绩低于70分的提高5%。

4)WHILE语句

如有需要重复执行的Transact-SQL语句或语句块,可以使用WHILE语句。只要指定的条件为真,就重复执行语句或语句块。可以使用BREAK和CONTINUE关键字在循环内部控制WHILE循环中语句的执行。WHILE语句的基本格式如下:

说明:

boolean_expression:返回TRUE或FALSE的表达式,如果布尔表达式中含有SELECT 语句,则必须用圆括号将SELECT语句括起来;

sql_statement|statement_block:Transact-SQL语句或语句块,若要使用语句块,需使用BEGIN...END语句;

BREAK:将从最内层的WHILE循环中退出;

CONTINUE:使WHILE循环重新开始执行,忽略CONTINUE关键字后面的语句;

WHILE语句可以嵌套。如果嵌套了两个或多个WHILE循环,则内层的BREAK将退出到下一个外层循环。退出后将首先运行内层循环结束之后的所有语句,然后重新开始下一个外层循环。

【例3.87】 WHILE示例。

本例中,如果平均分低于75分,则WHILE循环将成绩提高5%,然后查询最高分;如果最高分小于等于95分,则WHILE循环重新开始,并再次将成绩提高5%;该循环不断地将成绩提高5%,直到最高分超过95分或平均分不再低于75分,才退出WHILE循环,并输出一条消息。

5)WAITFOR语句

使用WAITFOR语句,可以阻止执行批处理、存储过程或事务,直到已过指定的时间或时间间隔,其基本格式如下:

说明:

DELAY:指定可以继续执行批处理、存储过程或事务之前必须经过的时段,最长可为24小时;

TIME:指定运行批处理、存储过程或事务的时间点。

【例3.88】 两个小时后执行存储过程sp_helpdb。

WAITFOR DELAY 02:00;

EXEC sp_helpdb;

6)RETURN语句

RETURN语句用于从查询或过程中无条件退出。RETURN的执行是即时且完全的,可在任何时候用于从过程、批处理或语句块中退出,RETURN之后的语句不再执行。其基本格式如下:

说明:

integer_expression:返回的整数值。存储过程可向执行调用的过程或应用程序返回一个整数值。除非另外说明,否则所有系统存储过程都将返回一个0值。0值表示成功,非0值表示失败。