SQL 语句从上到下依序执行。Transact-SQL 提供了流程控制语句,使您能更改程序执行的顺序。您可以在批、语句块或存储过程中使用这些语句。在语句中使用这些关键字可为您提供编程语言(如 C 和 Visual Basic)具有的一些能力。
下面列出了 Transact-SQL 的流程控制语言中的关键字。
1、BEGIN...END 关键字
您可使用 BEGIN 和 END 关键字来创建 SQL 语句块。BEGIN 和 END 块间的语句按单个语句块处理,按一个单元执行。BEGIN 和 END 通常用于定义包含其他流程控制语句(如 IF、WHILE 及 CASE)的语句块。
语法:
BEGIN
{sql_statement | statement_block}
END
BEGIN...END 语句的 sql_statement | statement_block 部分表示任何有效的 Transact-SQL 语句分组。
下面的示例创建的简单代码块将打印出一条消息,并显示有关现代烹饪的书籍名称。
BEGIN
PRINT "This code block displays the names of book titles on modern cooking"
SELECT title FROM titles WHERE type = 'mod_cook'
END
2、CASE 关键字
CASE 关键字使您可根据表达式的真假来确定是否返回某个值。可在允许使用表达式的任何位置使用这一关键字。
语法:
CASE expression
WHEN expression1 THEN expression1
[[WHEN expression2 THEN expression2] [...]]
[ELSE expressionN]
END
参数:
表达式
常量、列名、函数、子查询,或任何可与另一表达式进行比较的表达式。
WHEN...THEN
存留要进行比较的值或表达式。如果匹配,则使用 THEN 子句。
ELSE
如果所有 WHEN 子句均返回 FALSE,则使用该子句。
下面的示例以文字形式打印出付给作者的版税。这在需要以文字形式打印出支付的版税的应用程序中非常有用。
SELECT DISTINCT RoyaltyPerc =
CASE royalty
WHEN 10 THEN '10 WHEN 12 THEN '12 WHEN 14 THEN '14 WHEN 16 THEN '16
WHEN 18 THEN '18 WHEN 20 THEN '20
WHEN 22 THEN '22
WHEN 24 THEN '24 percent'
ELSE 'No royalty'
END
FROM roysched
3、GOTO 关键字
您可使用 GOTO 关键字将执行控制从代码中的一个位置转移至用户定义标签之后的另一位置。标签是带冒号的文本,用于标识转移执行控制的目标位置。
您可在过程、批或语句块的任何位置使用 GOTO 语句和标签,但不能转至 GOTO 命令所在批之外的标签。要提供额外灵活性,可在批中嵌套 GOTO 语句和标签。
语法:
GOTO 标签
标签必须遵循标识符的命名规则。
例如,在下面的代码中使用 GOTO,可跳过不希望执行的代码段。
BEGIN
SELECT DISTINCT job_id FROM employee
GOTO SkipSelect
SELECT * FROM jobs
SkipSelect:
PRINT 'The second SELECT did not get executed'
END
4、IF...ELSE 关键字
如果需要在执行一组语句前先测试条件,则会在代码中同时存在几种情况。为此,您可使用 IF 和 ELSE 关键字来求布尔表达式的值。IF 部分提出问题,回答只能是 TRUE 或 FALSE。接着您可基于回答来执行一组语句。可以向 IF 语句添加 ELSE 关键字,以便在 IF 返回 FALSE 时执行其他语句。
语法:
IF boolean_expression
{sql_statement | statement_block}
[ELSE IF boolean_expression
{sql_statement | statement_block}]
[ELSE
{sql_statement | statement_block}]
参数:
boolean_expression
返回 TRUE 或 FALSE 的表达式。布尔表达式可以包含圆括号中的 SELECT 语句。
sql_statement | statement_block
任何有效的 SQL 语句或语句块。
下面的示例检查当年某种书籍的销售图。您可根据获得的销售结果来显示相应消息。
IF (SELECT ytd_sales FROM titles WHERE title_id = 'BU2075') 10000
BEGIN
PRINT 'This title has had a great sale'
SELECT title FROM titles WHERE title_id = 'BU2075'
END
ELSE IF (SELECT ytd_sales FROM titles WHERE title_id = 'BU2075') 5000
PRINT 'This title has had an average sale'
ELSE
PRINT 'This title has had a poor sale'
5、RETURN(点击这里查看)
6、WAITFOR 关键字
您可使用 WAITFOR 语句来指定执行语句块、存储过程或事务的时间、时间间隔或事件。
语法:
WAITFOR {DELAY 'time' | TIME 'time'}
参数:
DELAY
指定事件发生之前所经过的时间间隔(最长为 24 小时)。
TIME
开始事务的时间。
time
任一可接受格式的日期时间数据,不包括日期部分中的日期。
下面的示例使用 WAITFOR 关键字测试 SELECT 语句的执行延迟。
SELECT "Seconds before WAITFOR" = DATEPART(second, getdate())
WAITFOR DELAY '00:00:10'
SELECT "Seconds after WAITFOR" = DATEPART(second, getdate())
7、WHILE 块
希望在遇到布尔条件之前重复执行语句时,可使用 WHILE 块。您还可使用 BREAK 和 CONTINUE 关键字来控制 WHILE 循环的执行。
BREAK 子句会导致退出 WHILE 循环。它通常与 IF 语句一起使用。与 RETURN 语句不同,BREAK 语句只会导致退出当前 WHILE 循环。WHILE 块之后的语句仍会执行。如果 BREAK 在嵌套的 WHILE 循环中执行,则 BREAK 退至下一外层循环。
CONTINUE 子句跳过 CONTINUE 关键字之后的所有语句并重新启动 WHILE 循环。该子句通常也与 IF 语句一起使用。
语法:
WHILE boolean_expression
{sql_statement | statement_block}
[BREAK]
{sql_statement | statement_block}
[CONTINUE]
参数:
boolean_expression
返回 TRUE 或 FALSE 的表达式。布尔表达式可包含圆括号中的 SELECT 语句。
sql_statement | statement_block
任何有效的 SQL 语句或语句块。
BREAK
退出 WHILE 循环。
CONTINUE
重新启动 WHILE 循环,跳过 CONTINUE 之后的任何语句。
下面的示例创建的批使用 WHILE 块来更新 titles 表中各书名的价格,直到平均书价高于 20 美元。该代码确保最高书价不会超过 30 美元。
WHILE (SELECT AVG(price) FROM titles WHERE price IS NOT NULL)
UPDATE titles
SET price = price + 1 WHERE price IS NOT NULL
SELECT MAX(price) FROM titles
IF (SELECT MAX(price) FROM titles) $30
BREAK
ELSE
CONTINUE
..........END
SELECT AVG(price) FROM titles WHERE price IS NOT NULL
SELECT MAX(price) FROM titles WHERE price IS NOT NULL
PRINT 'Update complete'
END