SQL 流程控制

Transact-SQL 提供了称为控制流语言的特殊关键字，这些关键字用于控制 Transact-SQL 语句、语句块、用户定义函数以及存储过程的执行流。

不使用控制流语言，则各 Transact-SQL 语句按其出现的顺序分别执行。控制流语言使用与程序设计相似的构造使语句得以互相连接、关联和相互依存。

当您需要 Transact-SQL 进行某种操作时，这些控制流关键字非常有用。例如，当在一个逻辑块中包含多个 Transact-SQL 语句时，请使用 BEGIN...END 语句对。使用 IF...ELSE 语句对的情况是：IF（如果）满足某条件，则执行某些语句或语句块，而如果不满足此条件（ELSE 条件）则执行另一条语句或语句块。

控制流语句不能跨多个批处理、用户定义函数或存储过程。

以下是控制流关键字。

BEGIN...END | BREAK
GOTO | CONTINUE
IF...ELSE | WHILE
RETURN | WAITFOR

## CASE 语句

CASE 具有两种格式：

简单 CASE 函数将某个表达式与一组简单表达式进行比较以确定结果。

CASE 搜索函数计算一组布尔表达式以确定结果。

两种格式都支持可选的 ELSE 参数。

语法

Simple CASE function: CASE input_expression

WHEN when_expression THEN result_expression

[ ...n ]

[

ELSE else_result_expression

]

END

Searched CASE function:

CASE

WHEN Boolean_expression THEN result_expression

[ ...n ]

[

ELSE else_result_expression

]

END

参数

input_expression

使用简单 CASE 格式时所计算的表达式。input_expression 是任意有效的表达式。

WHEN when_expression

使用简单 CASE 格式时要与 input_expression 进行比较的简单表达式。when_expression 是任意有效的表达式。input_expression 及每个 when_expression 的数据类型必须相同或必须是隐式转换的数据类型。

n

占位符，表明可以使用多个 WHEN when_expression THEN result_expression 子句或多个 WHEN Boolean_expression THEN result_expression 子句。

THEN result_expression

当 input_expression = when_expression 计算结果为 TRUE，或者 Boolean_expression 计算结果为 TRUE 时返回的表达式。result expression 是任意有效的表达式。

ELSE else_result_expression

比较运算计算结果不为 TRUE 时返回的表达式。如果忽略此参数且比较运算计算结果不为 TRUE，则 CASE 返回 NULL。else_result_expression 是任意有效的表达式。else_result_expression 及任何 result_expression 的数据类型必须相同或必须是隐式转换的数据类型。

WHEN Boolean_expression

使用 CASE 搜索格式时所计算的布尔表达式。Boolean_expression 是任意有效的布尔表达式。

结果类型

从 result_expressions 和可选 else_result_expression 的类型集中返回优先级最高的类型。

结果值

简单 CASE 函数：

计算 input_expression，然后按指定顺序对每个 WHEN 子句的 input_expression = when_expression 进行计算。

返回 input_expression = when_expression 的第一个计算结果为 TRUE 的 result_expression。

如果 input_expression = when_expression 计算结果不为 TRUE，则在指定 ELSE 子句的情况下 SQL Server 2005 数据库引擎将返回 else_result_expression；若没有指定 ELSE 子句，则返回 NULL 值。

CASE 搜索函数：

按指定顺序对每个 WHEN 子句的 Boolean_expression 进行计算。

返回 Boolean_expression 的第一个计算结果为 TRUE 的 result_expression。

如果 Boolean_expression 计算结果不为 TRUE，则在指定 ELSE 子句的情况下 数据库引擎将返回 else_result_expression；若没有指定 ELSE 子句，则返回 NULL 值。

示例

A. 使用带有简单 CASE 函数的 SELECT 语句

在 SELECT 语句中，简单 CASE 函数仅检查是否相等，而不进行其他比较。以下示例使用 CASE 函数更改产品系列类别的显示，以使这些类别更易理解。

1. USE AdventureWorks;

2. GO

3. SELECT ProductNumber, Category =

4. CASE ProductLine

5. WHEN 'R' THEN 'Road'

6. WHEN 'M' THEN 'Mountain'

7. WHEN 'T' THEN 'Touring'

8. WHEN 'S' THEN 'Other sale items'

9. ELSE 'Not for sale'

10. END,

11. Name

12. FROM Production.Product

13. ORDER BY ProductNumber;

14. GO

B. 使用带有简单 CASE 函数和 CASE 搜索函数的 SELECT 语句

在 SELECT 语句中，CASE 搜索函数允许根据比较值在结果集内对值进行替换。下面的示例根据产品的价格范围将标价显示为文本注释。

15. USE AdventureWorks;

16. GO

17. SELECT ProductNumber, Name, 'Price Range' =

18. CASE

19. WHEN ListPrice = 0 THEN 'Mfg item - not for resale'

20. WHEN ListPrice < 50 THEN 'Under $50'

21. WHEN ListPrice >= 50 and ListPrice < 250 THEN 'Under $250'

22. WHEN ListPrice >= 250 and ListPrice < 1000 THEN 'Under $1000'

23. ELSE 'Over $1000'

24. END

25. FROM Production.Product

26. ORDER BY ProductNumber ;

27. GO

C. 使用 CASE 代替 Microsoft Access 中使用的 IIf 函数

CASE 可与 Microsoft Access 中的 IIf 函数提供相似的功能。以下示例显示一个简单查询，它使用 IIf 为名为 db1.ContactInfo 的 Access 表中的 TelephoneInstructions 列提供输出值。

SELECT FirstName, Lastname, TelephoneNumber,

IIf(IsNull(TelephoneInstructions),"Any time",

TelephoneInstructions) AS [When to Contact]

FROM db1.ContactInfo

以下示例使用 CASE 为 AdventureWorks 视图中的 TelephoneSpecialInstructions 列提供输出值，该视图名称为 Person.vAdditionalContactInfo。

28. USE AdventureWorks

29. GO

30. SELECT FirstName, Lastname, TelephoneNumber, 'When to Contact' =

31. CASE

32. WHEN TelephoneSpecialInstructions IS NULL THEN 'Any time'

33. ELSE TelephoneSpecialInstructions

34. END

35. FROM Person.vAdditionalContactInfo

36.

PRINT 语句

向客户端返回用户定义消息。

语法

PRINT msg_str | @local_variable | string_expr

参数

msg_str

字符串或 Unicode 字符串常量。

@local_variable

任何有效的字符数据类型的变量。@local_variable 的数据类型必须是 char 或 varchar，或者必须能够隐式转换为这些数据类型。

string_expr

返回字符串的表达式。可包括串联的文字值、函数和变量。消息字符串最长可为 8,000 个字符，超过该值以后的任何字符均被截断。

示例

A. 有条件地执行 PRINT (IF EXISTS)

本示例使用 PRINT 语句有条件地返回消息。

IF @@OPTIONS & 512 <> 0

PRINT N'This user has SET NOCOUNT turned ON.';

ELSE

PRINT N'This user has SET NOCOUNT turned OFF.';

GO

B. 生成并显示字符串

本示例将 GETDATE 函数的结果转换为 varchar 数据类型，并将其与 PRINT 要返回的文本串联。

-- Build the message text by concatenating

-- strings and expressions using functionality

-- available in SQL Server 2000 and SQL Server 2005.

PRINT N'This message was printed on '

+ RTRIM(CAST(GETDATE() AS NVARCHAR(30)))

+ N'.';

GO

-- This example shows building the message text

-- in a variable and then passing it to PRINT.

-- This was required in SQL Server 7.0 or earlier.

DECLARE @PrintMessage NVARCHAR(50);

SET @PrintMessage = N'This message was printed on '

+ RTRIM(CAST(GETDATE() AS NVARCHAR(30)))

+ N'.';

PRINT @PrintMessage;

GO