码迷,mamicode.com
首页 > 数据库 > 详细

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

时间:2015-04-01 20:12:21      阅读:274      评论:0      收藏:0      [点我收藏+]

标签:程序设计   用户   

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

在以下示例中,如果品的平均价小于$300WHILE 将价格乘2,然后选择最高价格。如果最高价格小于或等于$500WHILE 重新开始,并再次将价格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

求例:

分行打印字符12345

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。在其他情况下(StateProvinceWA 以外的,或者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 版本中,则对逻辑阶段的描述展到了所有的逻辑语句,而不仅仅理,如APPLYPIVOT等。按种分方式,将逻辑分成了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 1FROM):中用于验证查询的源表,并理表操作符。每个表操作符用于一系列子步。例如,在上面用于接的(1-J)步中会涉及如下的子步。最终这些子步完成后,将生成虚VT1

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

VT1-J1

1-J2):笛卡儿乘积应ON 筛选器,生成虚VT1-J2

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

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

l 2WHERE):VT1 WHERE 筛选器,将符合筛选条件的行插入到VT2 中。

l 3GROUP BY):按GROUP BY子句中的列列表VT2中的行分,生成VT3

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

l 4HAVING):VT3 HAVING 筛选器,将符合筛选条件的行插入到VT4

l 5SELECT):SELECT 子句中的元素,生成VT5

5-1算表达式:骤计SELECT 列表中的表达式,生成VT5-1

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

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

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

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


本文出自 “Ricky's Blog” 博客,请务必保留此出处http://57388.blog.51cto.com/47388/1627409

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

标签:程序设计   用户   

原文地址:http://57388.blog.51cto.com/47388/1627409

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!