T-SQL流程控制语句

时间:2022-07-15 10:17:03 阅读: 最新文章 文档下载
说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。
u 学习IFELSE,条件语句

u 学习WHILECONTINUEBREAK,循环语句 u 学习CASE,多条件分支语句 u 学习GOTO,跳转语句

u 学习Try Catch,错误与意外处理语句

流程控制语句是指那些用来控制程序执行和流程分支的语句,SQL Server 2000中,流程控制语句主要用来控制SQL语句、语句块或者存储过程的执行流程。 2-2-1 IFELSE语句 在流程控制语句之中,首先我们应当认识的是语句块,一个语句块是以BEGIN开始,END语句作为终止,作为一个完全独立的逻辑单元存在于流程控制语句之中,如下所示: BEGIN

{ sql_statement | statement_block } END

IFELSE语句是条件判断语句,其中,ELSE子句是可选的,最简单的IF语句没有ELSE子句部分。IFELSE语句用来判断当某一条件成立时执行某段程序,条件不成立时执行另一段程序。SQL Server允许嵌套使用IFELSE语句,而且嵌套层数没有限制。IFELSE语句的语法形式为: IF Boolean_expression

{ sql_statement | statement_block } [ ELSE

{ sql_statement | statement_block } ] 实验: IFELSE语句实验

--1:如果员工数据表中有人在办公室工作,则显示这些人名单,否则告知没有人在办公室。

如果选修课程数据表中有不及格的同学,则显示这些同学的名单和成绩,否则显示无。 Use sample Go

--声明用于发布消息的变量 Declare @message varchar(200) --判断是否在办公室工作

If exist(Select * from 员工数据表 where 所属部门=’办公室’) --如果有,则列出姓名 Begin

set @message=’下列人员在办公室: print @message

select 姓名 from 员工数据表 where 所属部门=’办公室’ End

--否则,输出没有人的在工作的消息 Else Begin

Set @message=’抱歉,没有人在办公室’ Print @message End


Go

--注意:begin end分别表示语句块的开始和结束,而且他们必须成对使用。

--例子2:查询如果有工资超过5000元输出一个消息,否则输出另一个消息

Use sample Go

Declare @message varchar(200)

--判断是否存在工资超过5000的员工

If exist(Select 姓名,工资 from 员工数据表 where 工资>5000) Begin

Print ’有员工工资超过5000元’ End

--否则,输出没有工资以上的员工 Else Begin

Set @message=’抱歉,并没有员工的工资在5000元以上’ Print message End

--例子3:下面的例子中,如果员工平均薪水大于3000元,则输出一个消息,否则输出另一个消息

If (select avg(工资) from 员工数据表)>3000 print ’我们要求提高工资水平! Else

print ’工资水平较为合理!

2-2-2 WHILECONTINUEBREAK语句

WHILECONTINUEBREAK语句用于设置重复执行SQL语句或语句块的条件。只要指定的条件为真,就重复执行语句。其中,CONTINUE语句可以使程序跳过CONTINUE语句后面的语句,回到WHILE循环的第一行命令。BREAK语句则使程序完全跳出循环,结束WHILE语句的执行,其语法形式为: WHILE Boolean_expression

{ sql_statement | statement_block } [ BREAK ]

{ sql_statement | statement_block } [ CONTINUE ]

实验: WHILECONTINUEBREAK语句实验

--1下面的这个例子将判断如果员工平均薪水少于3000元,则循环每次使得每个员工工资增加5元,直到所有的员工的平均工资都是大于3000元或者有的员工的工资超过了10000元为止。

如果所有同学平均成绩少于80分,则循环每次使得每个学生成绩增加5分,直到所有的学生的平均成绩都大于80分。




Use sample Go

--根据是否存在员工的平均工资少于3000而确定循环是否继续执行 While (select avg(工资) from 员工数据表)<3000 --循环开始 begin

Update 员工数据表 Set 工资=工资+5

--如果有的员工的工资已经超过了10000元,则跳出循环 print '没有的员工的工资已经超过了10000元,继续循环' If (select max(工资) from 员工数据表)>10000 Break else

continue end

--循环结束

print '有的员工的工资已经超过了10000元,停止循环' --2、另一种解法示例

declare @salary money,@min_money money,@max_money money,@avg_money money

select @min_money=MIN(工资),@max_money=MAX(工资),@avg_money=AVG(工资) FROM 员工数据表

while @avg_money<3000 begin

update 员工数据表 set 工资=工资+500 if @max_money>10000 break else

continue End

--小问题:案例2出现死循环了,怎么解决? 问题分析:由于例2代码的第二行所查询出来的数据是初次数据表的最小值、最大值和平均值,这些数据不会在后面的循环过程的累加变化中而动态变化,即循环条件永远满足,从而导致死循环的产生。 --2、错误更正(1

declare @salary money,@min_money money,@max_money money,@avg_money money --此处是进行局部变量的初次赋值;

select @min_money=MIN(工资),@max_money=MAX(工资),@avg_money=AVG(工资) FROM 员工数据表

while @avg_money<3000 begin

--此处赋值是每次循环时候,改变各个变量的值。

select @min_money=MIN(工资),@max_money=MAX(工资),@avg_money=AVG(工资) FROM 员工数据表

update 员工数据表 set 工资=工资+500


if @max_money>10000 break else

continue End

--小问题:案例2的错误更正虽然解决了死循环的问题,但是依然是错误的,为什么? 主要原因是在进行update修改数据后,并没有及时赋值,程序将继续开始循环,但此时while判断的@avg_money变量的值已经不是最新的了,从而导致循环次数可能变多一次。 --2、错误更正(2

declare @salary money,@min_money money,@max_money money,@avg_money money --此处是进行局部变量的初次赋值;

declare @salary money,@min_money money,@max_money money,@avg_money money select @min_money=MIN(工资),@max_money=MAX(工资),@avg_money=AVG(工资) FROM 员工数据表

while @avg_money<3000 begin

update 员工数据表 set 工资=工资+500 if @max_money>10000 break else

begin

--调整位置,每次continue之前先进性赋值。

select @min_money=MIN(工资),@max_money=MAX(工资),@avg_money=AVG(工资) FROM 员工数据表 continue end End

--2、错误更正(3,本方法比较简洁明了。 while (select AVG(工资) from 员工数据表)<3000 begin

update 员工数据表 set 工资=工资+500

if (select max(工资) from 员工数据表)>10000 break else

continue End

2-2-3 CASE语句

CASE语句可以计算多个条件式,并将其中一个符合条件的结果表达式返回。CASE语句按照使用形式的不同,可以分为简单CASE语句和搜索CASE语句,它们的语法形式分别为: CASE input_expression

WHEN when_expression THEN result_expression [ ...n ]

[ELSE else_result_expression ENDCASE

WHEN Boolean_expression THEN result_expression


[...n ]

[ELSE else_result_expression END 实验: CASE语句实验

--1:根据员工数据表中每个员工所在不同部门,显示不同的信息 Use sample Go

Select 姓名, ’部门说明’= --分别为各个部门说明情况 Case 所属部门

when ’办公室’ then ’在办公室工作,该部门主要负责办公室的工作。 when ’项目部’ then ’在项目部工作,该部门主要负责项目部的工作。 when ’录入部’ then ’在录入部工作,该部门主要负责录入部的工作。 when ’技术部’ then ’在技术部工作,该部门主要负责技术部的工作。 End

From 员工数据表 --按照员工的数据表排序 Order by 姓名

2-2-4 waitfor语句

WAITFOR语句用于暂时停止执行SQL语句、语句块或者存储过程等,直到所设定的时间已过或者所设定的时间已到才继续执行。WAITFOR语句的语法形式为: WAITFOR { DELAY 'time' | TIME 'time' }

其中,DELAY用于指定时间间隔,TIME用于指定某一时刻,其数据类型为datetime,格式为‘hh:mm:ss

实验: waitfor语句实验 --1 Use sample Go

--指定在执行select语句之前需要等待3 Waitfor delay 00:00:03 --执行查询

select 姓名,性别 from 员工数据表 where 所属部门=’项目部’ 2-2-5 GOTO语句

GOTO语句可以使程序直接跳到指定的标有标识符的位置处继续执行,而位于GOTO语句和标识符之间的程序将不会被执行。GOTO语句和标识符可以用在语句块、批处理和存储过程中,标识符可以为数字与字符的组合,但必须以“: ”结尾。如:a1: 。在GOTO语句行,标识符后面不用跟“: GOTO语句的语法形式为: GOTO label(标签名称) „„ label:

实验: GOTO语句实验

--1利用GOTO语句求出从1加到5的总和。程序清单如下: declare @sum int, @count int select @sum=0, @count=1 label_1:

select @sum=@sum+@count


select @count=@count+1 if @count<=5 goto label_1

select @count @sum --注意:

人们认为GOTO语句是影响可读性的严重因素,在使用的时候尽可能避免使用GOTO语句,因为过多的GOTO语句可能会造成T-SQL的逻辑混乱而难以理解。另外,标签仅仅标示了跳转的目标,它并不隔离其前后的语句。只要标签前面的语句本身不是流程控制语句,标签前后的语句将按照顺序正常执行,就如同没有使用标签一样。 2-2-6 错误处理与Try Catch语句

这是MSSQL2005特有的一种标准的捕获和处理错误的方法,其基本理念是,尝试执行一个代码块,如果发生错误,则在Catch代码块之中捕获错误,其基本用法如下: BEGIN TRY

{ sql_statement | statement_block } ; END TRY

BEGIN CATCH

{ sql_statement | statement_block } END CATCH

和普通语言的异常处理用法差不多,但要注意的是,SQL SERVER只捕捉那些不是严重的异常,当比如数据库不能连接等这类异常时,是不能捕捉的。在捕获异常错误时候,经常会使用到一些系统的错误函数,具体内容见表2-3所示。 2-3 异常出错时候使用的捕获错误的系统函数

错误函数 Error_Message() Error_Number() Error_Procedure() Error_Serverity() Error_State()

返回值 错误的消息文本 错误编号

发生错误的存储过程或触发器的名称 错误的严重程度 错误的状态

在进行异常捕获时候,对于CATCH块我们需要注意处理好下面的工作: (1) 如果批处理使用了逻辑结构(begin tran/commit tran,则错误处理程序应回滚事务。建议首先会滚事务,以释放该事务执行的锁定。

(2) 如果错误是存储过程逻辑检测到的,则系统将自动引发错误消息。 (3) 如果有必要,将错误记录到错误表中。

(4) 结束批处理,如果它是存储过程、用户定义函数或触发器,可使用return命令结束它。

实验: GOTO语句实验

--1:除0错误时候,捕获异常错误: BEGIN TRY

DECLARE @X INT -- 0作为除数错误 SET @X = 1/0

PRINT 'TRY模块运行正常' END TRY

BEGIN CATCH


PRINT '出现异常错误'

SELECT ERROR_NUMBER() ERNumber, ERROR_SEVERITY() Error_Severity, ERROR_STATE() Error_State,

ERROR_PROCEDURE() Error_Procedure, ERROR_LINE() Error_Line,

ERROR_MESSAGE() Error_Message END CATCH

PRINT 'TRY/CATCH执行完毕后显示信息' --2trycatch可以嵌套的案例 Use school GO

Begin TRY

delete from student where sName = '小明' print '小明同学已经被成功删除。' End Try Begin Catch

Print '删除信息时候有错误发生' Begin Try

delete from score where sno = (select distinct sno from student where sName = '小明') Print '小明同学第二次被成功删除。' End Try Begin Catch

print '删除信息第二次错误发生' Begin Try

delete from student where sno =

(select distinct sno from score where cno = (select distinct cno from course where cName = 'c语言'))

print '第三次删除学生成功。' End Try Begin Catch

Print '删除信息第三次错误发生' End Catch End Catch End Catch


本文来源:https://www.wddqw.com/doc/c277e935a46e58fafab069dc5022aaea998f41eb.html