29. SQL -- T-SQL 流程控制语句

T-SQL 流程控制语句

Transact-SQL 语言提供了一些可以用于改变语句执行顺序的命令,称为流程控制语句。流程控制语句允许用户更好地组织存储过程中的语句,方便地实现程序的功能。流程控制语句与常见的程序设计语言类似,主要包含以下几种。

T-SQL 的流程控制语句:

IF…ELSE

BEGIN…END

CASE

WHILE…CONTINUE…BREAK

WAITFOR

GOTO

RETURN

IFELSE 语句:

指定 Transact-SQL 语句的执行条件。如果满足条件,则在 IF 关键字及其条件之后执行 Transact-SQL语句:布尔表达式返回 TRUE。可选的 ELSE 关键字引入另一个Transact-SQL 语句,当不满足 IF 条件时就执行该语句:布尔表达式返回 FALSE。IF...ELSE 构造可用于批处理、存储过程和即时查询。当此构造用于存储过程时,通常用于测试某个参数是否存在。

IFELSE 语句:

IF Boolean_expression

{ sql_statement |statement_block }

[ ELSE

{ sql_statement |statement_block } ]

IF<< span="">条件表达式>

<< span="">命令行或程序块>

[ELSE[条件表达式]

<< span="">命令行或程序块>]

其中<< span="">条件表达式>可以是各种表达式的组合,但表达式的值必须是“真”或“假”。ELSE

子句是可选的。IFELSE 语句用来判断当某一条件成立时执行某段程序,条件不成立时执行另一段程序。如果不使用程序块,IF 或ELSE 只能执行一条命令。IFELSE 可以嵌套使用,最多可嵌套32 级

参数:

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

{sql_statement | statement_block }:任何 Transact-SQL 语句或用语句块定义的语句分组。除非使用语句块,否则IF 或 ELSE 条件只能影响一个 Transact-SQL 语句的性能。若要定义语句块,请使用控制流关键字BEGIN 和 END

可以在其他 IF 之后或在 ELSE 下面,嵌套另一个 IF 测试。嵌套级数的限制取决于可用内存

示例:在 uspGetList 存储过程的输出中使用了IFELSE。该存储过程在创建存储过程中定义。在此示例中,该存储过程返回标价低于700 美元的自行车清单。这将导致执行第一个 PRINT 语句

DECLARE @compareprice money,@cost money

EXECUTEProduction.uspGetList ‘%Bikes%‘, 700,

@compareprice OUT,

@cost OUTPUT

IF @cost <= @compareprice

BEGIN

PRINT ‘These products can bepurchased for less than

$‘+RTRIM(CAST(@comparepriceAS varchar(20)))+‘.‘

END

ELSE

PRINT ‘The prices for allproducts in this category exceed

$‘+ RTRIM(CAST(@comparepriceAS varchar(20)))+‘.‘

创建一个随机数/2,看是否余数为0,若为0,返回a,若不为0,返回b

declare @num int

set @num =(convert(int,RANd (11)*100000))

if @num % 2=0

print ‘a‘

else

print ‘b‘

 

BEGIN…END 语句

BEGIN 和 END 语句用于将多个Transact-SQL 语句组合为一个逻辑块。在控制流

语句必须执行包含两条或多条Transact-SQL 语句的语句块的任何地方,都可以使用

BEGIN 和 END 语句。

EGIN END 语句用于下列情况:

WHILE 循环需要包含语句块。

CASE 函数的元素需要包含语句块。

IF 或 ELSE 子句需要包含语句块。

语法:

BEGIN

{

sql_statement |statement_block

}

END

参数:{ sql_statement | statement_block }使用语句块定义的任何有效的Transact-SQL

语句或语句组

示例:

A、在下面的示例中,BEGIN 和 END 定义一系列一起执行的Transact-SQL语句。如

果不包括 BEGIN...END 块,则将执行两个ROLLBACKTRANSACTION 语句,并返回

两条 PRINT 消息

USE AdventureWorks;

GO

BEGIN TRANSACTION;

GO

IF @@TRANCOUNT = 0

BEGIN

SELECT *

from Person.Contact

WHERE LastName = ‘ADAMS‘;

ROLLBACK TRANSACTION

PRINT N‘Rolling back thetransaction two times would cause an error.‘

END

ROLLBACK TRANSACTION

PRINT N‘Rolled back thetransaction.‘

GO

/*

Rolled back the tranaction.

*/

B、创建一个测试表,并循环写入500 条数据,使用newid():

declare @num int =1

while @num <=< span="">500

begin

print ‘test‘

set @num=@num+1

end

CASE

计算条件列表并返回多个可能结果表达式之一。

CASE 具有两种格式:

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

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

CASE 语法:

Simple CASEfunction:

CASE input_expression

WHEN when_expression THENresult_expression

[ ...n ]

[

ELSE else_result_expression

]

END

SearchedCASE function:

CASE

WHEN Boolean_expression THENresult_expression

[ ...n ]

[

ELSE else_result_expression

]

END

参数:

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

有效的表达式。

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

n :占位符,表明可以使用多个 WHEN when_expressionTHEN result_expression 子句或多个 WHEN Boolean_expression THEN result_expression 子句。

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

ELSEelse_result_expression:比较运算计算结果不为TRUE 时返回的表达式。如果忽略此参数且比较运算计算结果不为TRUE , 则CASE 返回 NULL 。

else_result_expression 是任意有效的表达式。else_result_expression 及任何

result_expression 的数据类型必须相同或必须是隐式转换的数据类型。

WHENBoolean_expression : 使用 CASE 搜索格式时所计算的布尔表达式。

Boolean_expression 是任意有效的布尔表达式。

结果值:

简单CASE 函数:

l 计算input_expression, 然后按指定顺序对每个WHEN 子句的

input_expression =when_expression 进行计算。

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

result_expression。

l 如果 input_expression = when_expression 的计算结果均不为TRUE,则在指定了 ELSE 子句的情况下, SQL Server 数据库引擎将返回

else_result_expression;若没有指定 ELSE 子句,则返回NULL 值。

CASE 搜索函数:

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

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

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

示例:

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

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

USE AdventureWorks;

GO

SELECT ProductNumber,Category =

CASE ProductLine

WHEN ‘R‘ THEN ‘Road‘

WHEN ‘M‘ THEN ‘Mountain‘

WHEN ‘T‘ THEN ‘Touring‘

WHEN ‘S‘ THEN ‘Other saleitems‘

ELSE ‘Not for sale‘

END,

Name

FROM Production.Product

ORDER BY ProductNumber;

GO

B、使用带有CASE 搜索函数的 SELECT 语句

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

USE AdventureWorks;

GO

SELECT ProductNumber, Name,‘Price Range‘ =

CASE

WHEN ListPrice = 0 THEN ‘Mfgitem - not for resale‘

WHEN ListPrice < 50 THEN‘Under $50‘

WHEN ListPrice >= 50 andListPrice < 250 THEN ‘Under $250‘

WHEN ListPrice >= 250 andListPrice < 1000 THEN ‘Under $1000‘

ELSE ‘Over $1000‘

END

FROM Production.Product

ORDER BY ProductNumber ;

GO

 

WHILE…CONTINUE…BREAK

只要指定的条件为True 时,WHILE 语句就会重复语句或语句块。

下面两个 Transact-SQL 语句通常和WHILE 一起使用:REAK 或 CONTINUE。

BREAK 语句退出最内层的WHILE 循环,CONTINUE 语句则重新开始WHILE 循环。例如,如果没有其他行可以处理,程序可能执行BREAK 语句。例如,如果要继续执行代码,则可以执行CONTINUE 语句。

如果将 SELECT 语句用作WHILE 语句的条件,则SELECT 语句必须在括号中

语句:

WHILE << span="">条件表达式>

BEGIN

<< span="">命令行或程序块>

[BREAK]

[CONTINUE]

[命令行或程序块]

END

WHILE 命令在设定的条件成立时会重复执行命令行或程序块。

CONTINUE 命令可以让程序跳过CONTINUE 命令之后的语句,回到WHILE 循环的第一行命令。

BREAK 命令则让程序完全跳出循环,结束WHILE 命令的执行。

WHILE 语句也可以嵌套。

示例:

A、在游标中使用WHILE

下面的示例使用 WHILE 语句控制执行的提取数。

USE AdventureWorks;

GO

DECLARE abc CURSOR FOR

SELECT * FROMPurchasing.ShipMethod;

OPEN abc;

FETCH NEXT FROM abc

WHILE (@@FETCH_STATUS = 0)

FETCH NEXT FROM abc;

CLOSE abc;

DEALLOCATE abc;

GO

B. 在嵌套的 IF...ELSE WHILE 中使用 BREAK CONTINUE

在以下示例中,如果产品的平均标价小于$300,则WHILE 循环将价格乘2,然后选择最高价格。如果最高价格小于或等于$500,则WHILE 循环重新开始,并再次将价格乘 2。该循环不断地将价格乘2,直到最高价格超过$500,然后退出 WHILE 循环,并输出一条消息。

USE AdventureWorks;

GO

WHILE (SELECT AVG(ListPrice)FROM Production.Product) < $300

BEGIN

UPDATE Production.Product

SET ListPrice = ListPrice *2

SELECT MAX(ListPrice) FROMProduction.Product

IF (SELECT MAX(ListPrice)FROM Production.Product) > $500

BREAK

ELSE

CONTINUE

END

PRINT ‘Too much for themarket to bear‘;

C、创建一个数学运算表达式:

DECLARE @x INT, @y INT, @c INT

SELECT @x = 1, @y = 1

WHILE @x < 3

BEGIN

PRINT @x --打印变量x 的值

WHILE @y < 3

BEGIN

SELECT @c = 100*@x+ @y

PRINT @c --打印变量c 的值

SELECT @y = @y + 1

END

SELECT @x = @x + 1

SELECT @y = 1

END

返回结果:

1 101 102

2 201 202

WAITFOR

在达到指定时间或时间间隔之前,或者指定语句至少修改或返回一行之前,阻止执行

批处理、存储过程或事务.

语法:

WAITFOR

{

DELAY ‘time_to_pass‘

| TIME ‘time_to_execute‘

| [ ( receive_statement ) |( get_conversation_group_statement ) ]

[ , TIMEOUT timeout ]

}

参数:

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

‘time_to_pass ‘ :等待的时段。可以使用datetime 数据可接受的格式之一指定

time_to_pass,也可以将其指定为局部变量。不能指定日期;因此,

不允许指定datetime 值的日期部分。

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

‘time_to_execute ‘:WAITFOR 语句完成的时间。可以使用datetime数据可接受的格式之一指定 time_to_execute,也可以将其指定为局部变量。不能指

定日期;因此,不允许指定datetime值的日期部分。

receive_statement:有效的 RECEIVE语句。

get_conversation_group_statement:有效的 GETCONVERSATION GROUP 语句

TIMEOUT timeout:指定消息到达队列前等待的时间(以毫秒为单位)。

示例:

A. 使用 WAITFOR TIME

以下示例在晚上 10:20(22:20) 执行存储过程sp_update_job

USEmsdb;

EXECUTEsp_add_job @job_name = ‘TestJob‘;

BEGIN

WAITFORTIME ‘22:20‘;

EXECUTEsp_update_job @job_name = ‘TestJob‘,

@new_name= ‘UpdatedJob‘;

END;

GO

B、使用 WAITFOR DELAY

以下示例在两小时的延迟后执行存储过程。

BEGIN

WAITFORDELAY ‘02:00‘;

EXECUTEsp_helpdb;

END;

GO

C、等待1 小时2 分零3 秒后才执行SELECT 语句

WAITFORDELAY 01:02:03

SELECT* FROM Toys

D、等到晚上11 点零8 分后才执行SELECT 语句

WAITFORTIME 23:08:00

SELECT* FROM Toys

 

GOTO

将执行流更改到标签处。跳过GOTO 后面的 Transact-SQL语句,并从标签位置继续处理。GOTO 语句和标签可在过程、批处理或语句块中的任何位置使用。GOTO 语句

可嵌套使用,

语法:

Definethe label:

label:

Alterthe execution:

GOTOlabel

求例:

分行打印字符1、2、3、4、5。

DECLARE@x INT

SELECT@x = 1

lab_1:PRINT @x

SELECT@x = @x+ 1

WHILE@x < 6

GOTO lab_1

以下示例显示如何将GOTO 用作分支机制

DECLARE@Counter int;

SET @Counter = 1;

WHILE@Counter < 10

BEGIN

SELECT@Counter

SET @Counter = @Counter+ 1

IF @Counter = 4 GOTO Branch_One --Jumps to the first branch.

IF @Counter = 5 GOTO Branch_Two --This will never execute.

END

Branch_One:

SELECT‘Jumping To Branch One.‘

GOTO Branch_Three; --This will prevent Branch_Two from executing.

Branch_Two:

SELECT‘Jumping To Branch Two.‘

Branch_Three:

SELECT‘Jumping To Branch Three.‘

RETURN

RETURN命令用于结束当前程序的执行,返回到上一个调用它的程序或其它程序。

在括号内可指定一个返回值

语法:

RETURN[ integer_expression ]

求例:

A. 从过程返回:

以下示例显示如果在执行findjobs 时没有指定用户名作为参数,则RETURN将使过程

向用户屏幕发送一条消息后退出。如果指定了用户名,则将从相应的系统表中检索此用户

在当前数据库创建的所有对象名。

CREATEPROCEDURE findjobs @nm sysname = NULL

AS

IF @nm IS NULL

BEGIN

PRINT‘You must give a user name‘

RETURN

END

ELSE

BEGIN

SELECTo.name, o.id, o.uid

FROM sysobjects o INNERJOIN master..sysloginsl

ON o.uid = l.sid

WHEREl.name= @nm

END;

B. 返回状态代码

以下示例将检查指定联系人的ID 的状态。如果所在的州是Washington (WA),将返回状态代码1。在其他情况下(StateProvince的值是WA 以外的值,或者ContactID没有匹配的行),返回状态代码2。

USE AdventureWorks;

GO

CREATEPROCEDURE checkstate @param varchar(11)

AS

IF (SELECT StateProvinceFROM Person.vAdditionalContactInfo WHERE ContactID =

@param) = ‘WA‘

RETURN1

ELSE

RETURN2;

GO

T-SQL常用SQL 语句

语句 功能 语句 功能

数据操作

SELECT从数据库表中检索数据DELETE 从数据库表中删除数据行

INSERT向数据库表中添加数据行UPDATE更新数据库表中的数据

数据定义

CREATETABLE 创建一个数据库表CREATE

PROCEDURE

创建一个存储过程

DROPTABLE 从数据库中删除表DROP PROCEDURE 从数据库中删除存储过程

ALTERTABLE 修改数据库表结构CREATE TRIGGER 创建一个触发器

CREATEVIEW 创建一个视图DROPTRIGGER 从数据库中删除触发器

DROPVIEW 从数据库中删除视图CREATEDOMAIN 创建一个数据值域

CREATEINDEX 为数据库表创建一个索引ALTERDOMAIN 改变域定义

DROPINDEX 从数据库中删除索引DROP DOMAIN 从数据库中删除域

数据控制

GRANT授予用户访问权限REVOKE解除用户访问权限

DENY拒绝用户访问

事务控制

COMMIT结束当前事务SAVERANSACTION 在事务内设置保存点

ROLLBACK回滚当前事务

程序化SQL

DECLARE设定游标CLOSE 关闭游标

OPEN打开一个游标PREPARE 为动态执行准备SQL 语句

FETCH检索一行查询结果EXECUTE 动态执行SQL 语句

 

补充:

SQL 2005 查询过程:

在SQLServer 2005 版本中,将一个联接查询的逻辑处理分为了10 个步骤:

(8) SELECT (9) DISTINCT (11)

(1) FROM

(3) JOIN

(2) ON

(4) WHERE

(5) GROUP BY

(6) WITH {CUBE | ROLLUP}

(7) HAVING

(10) ORDER BY

SQL 2008 查询过程:

在SQLServer 2008 版本中,则对逻辑阶段的描述扩展到了所有的逻辑语句,而不仅仅是联接处理,如APPLY、PIVOT等。按这种分类方式,将逻辑步骤分成了6 部分,部分步骤中包含了子步骤。

(5)SELECT (5-2)DISTINCT (5-3) (5-1)

(1)FROM (1-J) JOIN ON

|(1-A) APPLY AS

|(1-P) PIVOT() AS

|(1-U) UNPIVOT() AS

(2)WHERE

(3)GROUP BY (3-CR)WITH {CUBE | ROLLUP}

(4)HAVING

(6)ORDER BY

各处理步骤流程描述:

l 步骤1(FROM):该步骤中用于验证查询的源表,并处理表操作符。每个表操作符应用于一系列子步骤。例如,在上面用于联接的(1-J)步骤中会涉及如下的子步骤。最终这些子步骤完成后,将生成虚拟表VT1。

(1-J1):执行left_table 和right_table两个表的交叉联接(笛卡儿乘积),生成

虚拟表VT1-J1;

(1-J2):对笛卡儿乘积应用ON 筛选器,生成虚拟表VT1-J2;

(1-J3):如果是外部联接,会在该步骤中将被ON 筛选掉的外部行添加到VT1-J2

中,生成VT1-J3。否则,将跳过该步骤。

l 步骤2(WHERE):对VT1 应用WHERE 筛选器,将符合筛选条件的行插入到VT2 中。

l 步骤3(GROUP BY):按GROUP BY子句中的列列表对VT2中的行分组,生成VT3。

如果语句中包含WITH CUBE 或WITH ROLLUP,则将分组统计结果再次加总后插入VT3,生成VT3-RC。

l 步骤4(HAVING):对VT3 应用HAVING 筛选器,将符合筛选条件的行插入到VT4。

l 步骤5(SELECT):处理SELECT 子句中的元素,生成VT5。

(5-1)计算表达式:该步骤计算SELECT 列表中的表达式,生成VT5-1;

(5-2)DISTINCT:从VT5-1中移除重复行,生成VT5-2;

(5-3)TOP:该步骤根据ORDER BY 子句中指定的排序规则,从VT5-2 的开始

处筛选出指定数量或比例的行。

l 步骤6(ORDER BY):该步骤对VT5-3 中的行按ORDERBY子句中的列列表进行排序,生成一个游标VC6

时间: 2024-09-30 12:41:50

29. SQL -- T-SQL 流程控制语句的相关文章

39. SQL -- 批处理及流程控制语句(1)

批处理及流程控制语句 批处理:(批处理语句,简称批语句): 是一组一起提交给SQL Server执行的SQL语句.当执行批处理语句的时候,SQL Server将批处理语句编译到一个称之为执行计划的可执行单元这有助于节省执行时间! 假如您必须执行10个SQL语句且你正在一个个的发送10个请求并执行它们,这个过程很浪费时间.且他们不能一起被执行!但你可以在一个批处理中执行所有的这10个SQL语句,且执行过程将变得很快,因为所有的SQL语句都一起被发送到SQL Server的服务器! 创建批处理语句:

40. SQL -- 批处理及流程控制语句(2)

  CASE语句 CASE函数可以计算多个条件式,并将其中一个符合条件的结果表达式返回.CASE函数按照使用形式的不同,可以分为简单CASE函数和搜索CASE函数. 简单CASE 函数将某个表达式与一组简单表达式进行比较以确定结果. CASE 搜索函数计算一组布尔表达式以确定结果. 简单CASE函数: 简单CASE表达式将一个测试表达式与一组简单表达式进行比较,如果某个简单表达式与测试表达式的值相等,则返回相应结果表达式的值.When子句提供测试值,并将When子句所指定的结果表达式返回.测试表

Oracle之PL/SQL编程_流程控制语句

选择语句 1. if...then 语句 语法: if < condition_expression > then plsql_sentence end if; condition_expression:表示一个条件表达式,其值为 true 时,程序会执行 if 下面的 PL/SQL 语句: 如果其值为 false,则程序会跳过if 下面的语句而 直接执行 end if 后边的语句. plsql_sentence:condition_expression 为 true 时,要执行的语句. 2.

[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆)

原文:[推荐]ORACLE PL/SQL编程详解之三:PL/SQL流程控制语句(不给规则,不成方圆) [推荐]ORACLE PL/SQL编程详解之三: PL/SQL流程控制语句(不给规则,不成方圆) ——通过知识共享树立个人品牌. 继上五篇: [顶]ORACLE PL/SQL编程详解之二:PL/SQL块结构和组成元素(为山九仞,岂一日之功) [推荐]ORACLE PL/SQL编程之四:把游标说透(不怕做不到,只怕想不到) [推荐]ORACLE PL/SQL编程之五:异常错误处理(知已知彼.百战不

PL/SQL之--流程控制语句

一.简介 像编程语言一样,oracle PL/SQL也有自己的流程控制语句.通过流程控制语句,我们可以在PL/SQL中实现一下比较复杂的业务逻辑操作.而无需到程序中去控制,在一定程度上提高了效率,这也是PL/SQL的强大之处.PL/SQL流程控制语句有如下几种: 控制语句: 包括IF 语句.CASE语句 循环语句: 包括LOOP语句, WHILE语句.FOR语句 顺序语句: 包括GOTO语句 二.语句种类 1.控制语句 a.IF语句 语法如下: IF 条件语句 TEHN 执行语句 ELSIF 条

SQL SERVER中的流程控制语句

流程控制语句 是指用来控制程序执行和流程分至点额命令,一般指的是逻辑计算部分的控制. 1.Begin End语句 封装了多个T-SQL语句组合,将他们组成一个单元来处理.一般在条件查询或者循环等控制流程语句中,要查询满足特定条件的操作时会用到.Begin--end可以嵌套使用. 语法如下: begin --<sql语句或程序块> end 例子 begin --<sql语句或程序块> select * from StudentInfo update StudentInfo set m

PL/SQL流程控制语句

PL/SQL流程控制语句介绍PL/SQL的流程控制语句, 包括如下三类:控制语句: IF 语句循环语句: LOOP语句, EXIT语句顺序语句: GOTO语句, NULL语句①if语句 IF <布尔表达式> THEN PL/SQL 和SQL语句; ELSIF< 其它布尔表达式> THEN 其它语句; ELSIF< 其它布尔表达式> THEN 其它语句; ELSE 其它语句; END IF; 例: declare v_emp_name employees.last_nam

MS SQL 流程控制语句

Declare   myCursor   cursor   For     Select   *   from   table1 open   myCursor         Fetch   next   From   myCursor   into   @变量     While   @@FETCH_STATUS   =0     begin           --处理单条记录           Fetch   next   From   myCursor     end Close  

pl/sql流程控制语句if else条件选择语句

if条件语句. if条件语句的基本结构 IF <布尔表达式> THEN PL/SQL 和 SQL语句 END IF; 或 IF <布尔表达式> THEN PL/SQL 和 SQL语句 ELSE 其它语句 END IF; declare cou number := &number; begin if cou >10 then dbms_output.put_line('cou='||cou); elsif cou<5 then dbms_output.put_li