67
第 17 第 Transact-SQL 第第 第第第第第 第第第第 第第第第 SQL 第第第第第第第第第第第第第 第第第第第第第 SQL 第第 第 CREATE VIEW ALTER VIEW DROP VIEW 第 第第第第 SQL 第第第第第第第 SQL 第第 第第第第第第 第第第第 第第第第第第第 第第第第第第第第第第第第第第 第第第第第第第 ,,; 第第第第第第第第第第第第 第第第第 第第第第第第 第第第 第第第第第第 第 、、,一, SQL 第第第第第第第第第 第第第第第第第第第第第第第第第第第第 ,。 1

第 17 章 Transact-SQL 结构化程序设计

Embed Size (px)

DESCRIPTION

第 17 章 Transact-SQL 结构化程序设计. 学习导读 前面介绍 SQL 语言都是根据其功能来划分的,如与视图有关的 SQL 语句有 CREATE VIEW 、 ALTER VIEW 、 DROP VIEW 等,因此这些 SQL 语句都是孤立的 SQL 语句,而且只能按照顺序执行,没有流程控制,也没有太强调中间数据的处理;而本章介绍的结构化程序设计将借助于变量、运算符、控制流语句,以及一些特殊语句,将 SQL 语句进行良好地组合,以结构化的程序形式实现更强大的功能。. 变量. - PowerPoint PPT Presentation

Citation preview

Page 1: 第 17 章  Transact-SQL 结构化程序设计

第 17 章 Transact-SQL 结构化程序设计学习导读 前面介绍 SQL语言都是根据其功能来划分的,如与视图有关的 SQL语句有 CREATE VIEW、 ALTER VIEW、 DROP VIEW等,因此这些 SQL语句都是孤立的 SQL语句,而且只能按照顺序执行,没有流程控制,也没有太强调中间数据的处理;而本章介绍的结构化程序设计将借助于变量、运算符、控制流语句,以及一些特殊语句,将 SQL语句进行良好地组合,以结构化的程序形式实现更强大的功能。

1

Page 2: 第 17 章  Transact-SQL 结构化程序设计

变量变量主要是用来存储 SQL语句执行后的值,以便更好地为其他 SQL语句所用。变量是程序自动化执行的关键,设想一下:如果没有变量存储 SQL语句执行结果,那么用户就需要手工记录其结果,并在下一次用到该结果时再输入。可以说,没有变量就没有程序。

2

Page 3: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句提到变量,其实前面在创建存储过程或函数时,已经用到了变量,而且存储过程(包括触发器)、函数以及 SQL脚本是变量最常用的 3个地方。变量在这 3个地方声明和使用的方法类似,但是其作用域不同,具体如下。

存储过程和函数中变量的作用域都是局部的。也就是说,在存储过程和函数中定义的变量不能够被其所在的存储过程和函数之外的 SQL语句访问,即使访问到,也不是其在存储过程和函数中的值。一般情况下,创建存储过程和函数的 SQL语句要位于开头或两个 GO语句之间。

3

Page 4: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句SQL脚本中的变量是全局变量。不过,并不是每一个SQL脚本中的变量都能够在整个 SQL脚本中使用 GO语句将 SQL脚本划分为几个独立的全局区域。被 GO语句分割的区域间的变量是不能够共享的。

GO语句是很重要的 SQL语句。它的功能具体表现在:当执行引擎遇到 GO语句时,将会清除前面语句定义的全局变量。如下语句演示 GO语句的用途:

4

Page 5: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句DECLARE @var_INT INT=100SELECT @var_INTGOSELECT @var_INT

5

Page 6: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句显然,上述第一个 SELECT语句成功执行,而 GO语句之后的 SELECT语句却失败,其失败的原因就在于 GO语句清楚了 GO语句之前的全局变量@var_INT。也就是说,在 GO语句之前定义的所有变量都将失效。

GO语句还有一个重要功能,就是等待其之前的语句执行完毕后,才开始执行其之后的语句,这个功能很重要,用户可能会经常碰到下面一条语句依赖于上面 SQL语句的情况,那么就需要确切地保证上一条 SQL语句成功执行后,再执行该 SQL语句。

6

Page 7: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句对于下面的 SQL语句,本意是先设置database_demo为当前数据库,然后在database_demo中创建一个表 tb_go,并插入一条记录。

USE database_demoCREATE TABLE tb_go(id INT PRIMARY KEY,name NCHAR(100),salary INT)INSERT INTO tb_go VALUES(2157,’LXP’,1000)

7

Page 8: 第 17 章  Transact-SQL 结构化程序设计

变量的作用域与 GO语句上述 SQL语句在执行时,可能会出错。这是因为SQLCMD或 SSMS在执行 SQL语句时,不是同步的,即不等待本条语句结束就自动开始执行下一条语句。对于本例来说, CREATE TABLE语句还没有成功执行,即表还没有创建成功, INSERT语句就开始向表中插入行记录信息了。

而 GO语句可以强制等待到本条 SQL语句成功执行后,再开始执行下一条 SQL语句。可以将上述的 SQL语句改写。

8

USE database_demoGOCREATE TABLE tb_go(id INT PRIMARY KEY,name NCHAR(100),salary INT)GOINSERT INTO tb_go VALUES(2157,’LXP’,1000)

Page 9: 第 17 章  Transact-SQL 结构化程序设计

定义变量在 SQL Server中,变量是通过 DECLARE语句声明的,并且使用 SET语句和 SELECT语句对变量进行赋值。如果在声明变量时,没有为变量指定初始值,那么在默认情况下, DECLARE声明的变量初始值为 NULL。完整的 DECLARE语句的语法较为复杂,笔者依据变量的数据类型,将其简化为以下几种情况。

9

Page 10: 第 17 章  Transact-SQL 结构化程序设计

定义变量1.系统数据类型如果定义变量的数据类型为 SQL Server系统数据类型,可以用如下方式定义:DECLARE @local_var AS data_type [=value][,..n]

组成元素的意义:@local_var是变量的名称,需要符合 SQL Server标识符规则。另外,变量的名称必须要以@开头,否则 DECLARE语句将会变为声明游标。

10

Page 11: 第 17 章  Transact-SQL 结构化程序设计

定义变量value是变量的初始值,其类型必须与变量声明类型匹配,或者在 SQL Server自动转换下是匹配的。data_type是 SQL Server提供的系统数据类型(除 TEXT, NTEXT或 IMAGE外)。

11

Page 12: 第 17 章  Transact-SQL 结构化程序设计

定义变量下面的 SQL语句声明了几种常用的变量,并指定了初始值:

DECLARE @var_INT INT=2157DECLARE @var_DATETIME DATETIME=GETDATE()DECLARE @var_FLOAT FLOAT=21.57DECLARE @var_BINARY BINARY(1000)=120DECLARE @var_NCHAR NCHAR(10)=‘LXP’DECLARE @var_XML XML=‘<student>LXP</student>’

BINARY这种变量最好少用,毕竟这种变量占用的内存较多。况且, BINARY运算起来也会过多地消耗资源,降低 SQL Server处理速度。

12

Page 13: 第 17 章  Transact-SQL 结构化程序设计

定义变量2.表类型如果定义变量的数据类型为表类型,那么可以使用如下方式定义表变量。DECLARE @table_var AS <table_type>

组成元素的意义:@table_var是 TABLE类型的变量的名称。变量同样要以@开头。<table_type>是表类型的结构,包括列定义、名称、数据类型和约束。约束只允许主键、唯一、空和检查。

13

Page 14: 第 17 章  Transact-SQL 结构化程序设计

定义变量下面的 SQL语句声明了一个表变量:

DECLARE @var_table ASTABLE(id INT NOT NULL,name NCHAR(10) NULL,PRIMARY KEY(id),UNIQUE(name),CHECK(id>2003))INSERT INTO @var_table VALUES(20033705,’LXP’)UPDATE @var_table SET name=‘LIN’ WHERE id=20033705SELECT * FROM @var_table

14

Page 15: 第 17 章  Transact-SQL 结构化程序设计

定义变量3.用户自定义表类型用户自定义表类型与表类型不同。因为用户自定义表类型是使用 CREATE TYPE创建的,并保存在数据库中;而表类型将在执行后消失,并不保存到数据库中。

如果定义变量的数据类型为用户自定义类型,那么可以用如下方式定义变量:DECLARE @user_var AS <user_table>

15

Page 16: 第 17 章  Transact-SQL 结构化程序设计

定义变量如下 SQL语句使用 CREATE TYPE创建了一个用户自定义表类型,并使用 DECLARE基于该表类型定义了一个表变量。无论是定义还是使用,表变量都和普通表类似。USE database_demoGOCREATE TYPE userdefine_tableASTABLE(id INT NOT NULL,name NCHAR(10) NULL,PRIMARY KEY(id),UNIQUE(name),CHECK(id>2003))

16

Page 17: 第 17 章  Transact-SQL 结构化程序设计

定义变量GODECLARE @var_table AS userdefine_tableINSERT INTO @var_table VALUES(20033705,’LXP’)UPDATE @var_table SET name=‘LIN’ WHERE id=20033705SELECT * FROM @var_table

17

Page 18: 第 17 章  Transact-SQL 结构化程序设计

常量常量也称标量值,其格式取决于其所表示值的数据类型。常量按照其值的类型不同,大致可以分为字符串常量、 Unicode字符串、二进制常量、 BIT常量、 DATETIME常量、 INTEGER常量、 DECIMAL常量、 FLOAT、 REAL常量、MONEY常量、 UNIQUEIDENTIFIER常量。其中,在表示负的数值常量时,只需在数值常量前加减号( -)即可。

18

Page 19: 第 17 章  Transact-SQL 结构化程序设计

常量1.字符串常量在 SQL Server中,字符串常量包含在单引号中。一般情况下,字符串常量是由字母( a~z、 A~ Z)、数字字符( 0~ 9)以及特殊字符( !,@,#)组成的。如果单引号中的字符串包含一个嵌入的引号,可以使用两个单引号表示嵌入的单引号。其中,空字符串是由两个没有任何字符的单引号(’’)表示。SELECT ‘The level #job_id:’’30%!,fox@foxma’’il.com’

19

Page 20: 第 17 章  Transact-SQL 结构化程序设计

常量2. Unicode字符串Unicode字符串的格式就是在普通字符串前面有一个大写的 N,如’ LXP’是字符串常量,而N’LXP’是一个 Unicode字符串变量。对于字符数据存储 Unicode数据时,每个字符使用 2个字节,而不是 1个字节。

3.二进制常量二进制常量是以 0x开头的数字串,但不是字符串,不需要单引号。由于采用十六进制表时,所以看起来像字符串。

20

Page 21: 第 17 章  Transact-SQL 结构化程序设计

常量4. BIT常量BIT常量其实是一种特殊的 INT常量,其有效值要么为 0,要么为 1,不需要单引号。

5. DATETIME常量DATETIME常量是由字符串组成的日期表示,如’ 2008-07-10 00:00:00.000’。

6. INTEGER常量INTEGER常量是由数字( 0~ 9)组成,没有小数点。

21

Page 22: 第 17 章  Transact-SQL 结构化程序设计

常量7. DECIMAL常量DECIMAL常量是由数字和小数点组成的小数。

8. FLOAT和 REAL常量FLOAT和 REAL常量是由科学记数法表示的小数,如 101.5E5(十进制为 10150000)。

9.MONEY常量以货币符号开头且包含小数点的数字串表示,一般情况下没有单引号。

22

Page 23: 第 17 章  Transact-SQL 结构化程序设计

常量10. UNIQUEIDENTIFIER常量用来表示 GUID的,可以使用字符串或二进制表示,’ 6F9619FF-8B86-B42D-00C04FC964CC’和0xff19966f868b11d0b42d00c04fc964cc是完全相同的 GUID。

23

Page 24: 第 17 章  Transact-SQL 结构化程序设计

运算符在 SQL Server 2008的 Transact-SQL语言中,运算符是很重要的部分,可以说对于数据的处理都要用到这些运算符。其实,运算符还是主要用于连接表达式、变量以及常量。不同的运算符其使用意义不同,返回值亦不同。本节将详细介绍这些运算符。

24

Page 25: 第 17 章  Transact-SQL 结构化程序设计

算术运算符在 SQL脚本中,算术运算符用来对两个表达式进行数学运算,其返回值的数据类型由参与运算的两个表达式的数据类型决定。而这两个表达式值的数据类型可以是相同的数据类型,也可以是能够被 SQL Server进行自动类型转换的数据类型。如果参与算术运算的两个表达式不能够被 SQL Server自动转换类型,那么将出错。

25

Page 26: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符在 SQL脚本中,逻辑运算符主要用于条件语句中,其返回值为 TRUE或 FALSE;算术运算符主要有ALL、 ANY( SOME)、 EXISTS、 IN、 LIKE、 AND、 NOT、 OR、 BETWEEN。

1. ALL关键字主要用于比较特定值和结果集的所有值。一般情况下, ALL与比较运算符配合使用。特定值 {=|<>|!=|>|>=|!>|<|<=|!<} ALL {结果集 }

26

Page 27: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符其中,当 SELECT语句结果集中的值都满足与特定值的比较时,才能返回 TRUE。USE database_demoGOCREATE TABLE tb_logic(salary INT)GOINSERT INTO tb_logic VALUES(1100)INSERT INTO tb_logic VALUES(1200)GOIF 1211>ALL(SELECT salary FROM tb_logic)

PRINT ‘所有的值都小于 1211’IF 1111>ALL(SELECT salary FROM tb_logic)

PRINT ‘所有的值都小于 1111’27

Page 28: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符2. ANY( SOME)关键字主要用于比较特定值和结果集中的所有值。一般也和比较运算符配合使用。特定值 {=|<>|!=|>|>=|!>|<|<=|!<} ALL {结果集 }

当 SELECT语句结果集中的值与特定值的比较时,有一个能满足就返回 TRUE。

28

Page 29: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符USE database_demoGOCREATE TABLE tb_logic(salary INT)GOINSERT INTO tb_logic VALUES(1100)INSERT INTO tb_logic VALUES(1200)GOIF 1211>ANY(SELECT salary FROM tb_logic)

PRINT ‘有值小于 1211’IF 1111>ANY(SELECT salary FROM tb_logic)

PRINT ‘有值小于 1111’

29

Page 30: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符3. EXISTS关键字用于测试一个子查询的结果集是否存在。如果结果集不为空,那么将返回 TRUE。EXISTS {SELECT语句 }使用 EXISTS的例子:USE database_demoGOCREATE TABLE tb_logic(salary INT)GOINSERT INTO tb_logic VALUES(1100)INSERT INTO tb_logic VALUES(1200)GO

30

Page 31: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符IF NOT EXISTS (SELECT * FROM tb_logic WHERE salary=1200)INSERT INTO tb_logic VALUES(1200)IF NOT EXISTS (SELECT * FROM tb_logic WHERE salary=1300)INSERT INTO tb_logic VALUES(1300)SELECT * FROM tb_logic

31

Page 32: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符4. IN关键字用于测试特定值是否在子查询的结果集中。如果特定值存在于结果集中,将返回 TRUE。特定值 [NOT] INT (SELECT查询 |值 [,…n])使用 IN的例子:USE database_demoGOCREATE TABLE tb_logic(salary INT)GOINSERT INTO tb_logic VALUES(1100)INSERT INTO tb_logic VALUES(1200)GO

32

Page 33: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符DECLARE @it INT=1300IF @it NOT IN (SELECT * FROM tb_logic)

INSERT INTO tb_logic VALUES(1300)SELECT * FROM tb_logicSELECT * FROM tb_logic WHERE salary IN (1100,1200)

33

Page 34: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符5. LIKE关键字用于测试特定字符串是否与指定模式匹配。在模式匹配过程中,模式的常规字符必须与特定字符串指定的字符完全匹配。但是,模式中的通配符可以与特定字符串的任意部分相匹配。 LIKE是一种字符串的模糊匹配。

特定字符串 [NOT] LIKE 模式 [ESCAPE escchar]

34

Page 35: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符USE database_demoGOCREATE TABLE tb_logic(name NCHAR(10))GOINSERT INTO tb_logic VALUES(‘LIU K’)INSERT INTO tb_logic VALUES(‘LIU C’)INSERT INTO tb_logic VALUES(‘LIN’)GOSELECT name FROM tb_logicWHERE name LIKE ‘LIU%’

35

Page 36: 第 17 章  Transact-SQL 结构化程序设计

逻辑运算符6.逻辑运算符( AND、 NOT、 OR、 BETWEEN)BETWEEN主要用于范围条件。USE database_demoGOCREATE TABLE tb_logic(salary INT)GOINSERT INTO tb_logic VALUES(1100)INSERT INTO tb_logic VALUES(1200)INSERT INTO tb_logic VALUES(1300)GOSELECT * FROM tb_logic WHERE salary BETWEEN 1000 AND 1300

36

Page 37: 第 17 章  Transact-SQL 结构化程序设计

赋值运算符在 SQL Server中,赋值运算符只有一个,即等号( =)。而 =主要用于 SELECT语句和SET语句。如下 SQL语句将定义一个@name变量,并使用赋值运算符给该变量赋值。

DECLARE @name NCHAR(10)SET @name=‘LXP’SELECT @nameSELECT @name=‘LIN’SELECT @name

37

Page 38: 第 17 章  Transact-SQL 结构化程序设计

字符串运算符加号( +)是常用的连接子字符串的运算符,其他的子字符串操作都是通过字符串函数进行的(如 LTRIM函数等)。如下 SQL语句将演示字符串运算符的用法

DECLARE @name NCHAR(10),@result NCHAR(10)SET @name=‘I MISS YOU’SELECT @result=@name+’, LIN’SELECT @result=SUBSTRING(@result,1,7)+’LIN’SELECT @result

38

Page 39: 第 17 章  Transact-SQL 结构化程序设计

按位运算符在 SQL Server中,位运算是一种特殊的运算符,主要是对两个整数转化为二进制后,再执行位运算,这种运算使用较少,但功能很强大,也很重要。

39

位运算 格式 运算结果

与( & )

表达式 1 & 表达式 2 表达式 1 、表达式 2 为 1 时值为 1 ,否则为 0

或( | ) 表达式 1 | 表达式 2 表达式 1 、表达式 2 有一个值为 1 时值为 1 ,否则为 0

异或( ^ )

表达式 1 ^ 表达式 2 表达式 1 、表达式 2 值不同时为 1 ,否则为 0

Page 40: 第 17 章  Transact-SQL 结构化程序设计

按位运算符DECLARE @var_INT_1 INT=223DECLARE @var_INT_2 INT=123SELECT @var_INT_1,@var_INT_2,@var_INT_1^@var_INT_2 AS ‘结果’

40

Page 41: 第 17 章  Transact-SQL 结构化程序设计

比较运算符在 SQL Server中,比较运算符是常用的运算符,主要用于比较两个表达式。DECLARE @var_INT_1 INT=223DECLARE @var_INT_2 INT=123IF @var_INT_1>@var_INT_2

PRINT ‘比较运算符: >’

41

Page 42: 第 17 章  Transact-SQL 结构化程序设计

复合运算符在 SQL Server中,除了上面的运算符外,还有一组复合运算符可以使用。这些符合运算符如表所示。

42

Page 43: 第 17 章  Transact-SQL 结构化程序设计

控制流语句在没有控制流语句的情况下, SQL语句只能顺序执行。控制流语句是结构化程序设计的关键保障,也称为控制流语言。显然,控制流语言为编写复杂的 SQL结构化程序提供了支持。有了上述的控制流语句后,才开始了实质性的 SQL结构化程序设计。在 SQL Server的 Transact-SQL中,控制流语言主要是指这样一组关键字,如 IF语句、WHILE语句、 BEGINEND语句、 RETURN语句等。在 SQL Server中,控制流语句可以支持嵌套,但是一个语句不能够跨多个批处理、用户自定义函数或存储过程使用。

43

Page 44: 第 17 章  Transact-SQL 结构化程序设计

BEGIN END语句BEGIN END语句可以将多个 SQL语句限制在其中,将多个 SQL语句当作一个逻辑执行块,所以 BEGIN END语句中的内容又被称为语句块。 BEGIN END语句至少要包括一条 SQL语句,否则将出错。

44

Page 45: 第 17 章  Transact-SQL 结构化程序设计

BEGIN END语句当在控制流语句中含有两条或多条SQL语句时,需要使用 BEGIN END语句。 BEGIN和 END语句主要用于以下情况:

IF或 ELSE子句的执行体。WHILE循环的执行体。CASE函数的执行体。

45

Page 46: 第 17 章  Transact-SQL 结构化程序设计

BEGIN END语句如下 IF语句中含有多条 SQL语句,所以需要使用 BEGIN END语句。IF @ret=100BEGININSERT INTO tb_logic VALUES(100)SELECT salary FROM tb_logicEND

46

Page 47: 第 17 章  Transact-SQL 结构化程序设计

BEGIN END语句如下不使用 BEGIN END语句,那么 SQL Server在执行如下语句时,将仅会把 INSERT语句作为 IF的一部分,而 SELECT语句则不属于 IF的执行体。IF @ret=100INSERT INTO tb_logic VALUES(100)SELECT salary FROM tb_logic

47

Page 48: 第 17 章  Transact-SQL 结构化程序设计

IF语句IF语句是最常用的控制流语句,用于简单条件的判断。 IF语句将会根据条件的值,指定 SQL语句的执行方向。当然,也可以使用 IF语句和ELSE子句配合以及 IF嵌套,编写复杂的条件判断。得到的控制流取决于是否指定了可选的ELSE语句。

48

Page 49: 第 17 章  Transact-SQL 结构化程序设计

IF语句1.不含 ELSE的 IF语句在不使用嵌套的情况下,这个 IF语句是最简单的情景。此时, IF语句只有一条执行路径,即要么执行,要么不执行。不含 ELSE的 IF语句的语法结构如下:IF (条件 )

语句或语句块也就是说,当 IF语句取值为 TRUE时,将执行IF语句后的语句或语句块; IF语句取值为FALSE时,跳过 IF语句后的语句或语句块。

49

Page 50: 第 17 章  Transact-SQL 结构化程序设计

IF语句USE database_demoGODELETE FROM tb_logicDECLARE @ret INT=100IF (@ret=100)BEGIN

INSERT INTO tb_logic VALUES(100)SELECT salary FROM tb_logic

END

50

Page 51: 第 17 章  Transact-SQL 结构化程序设计

IF语句2. IF ELSE语句在不使用嵌套的情况下, IF ELSE语句有两条执行路径,即要么执行 IF后面的语句块,要么执行 ELSE后的语句块,其语法结构如下:IF (条件 )

语句或语句块ELSE

语句或语句块即当条件取值为 TRUE时执行 IF后面的语句或语句块,否则执行 ELSE后面的。

51

Page 52: 第 17 章  Transact-SQL 结构化程序设计

IF语句USE database_demoGODELETE FROM tb_logicDECLARE @ret INT=100IF (@ret=100)BEGIN

INSERT INTO tb_logic VALUES(100)SELECT salary FROM tb_logic

ENDELSEBEGIN

UPDATE tb_logic SET salary=1200 WHERE salary=100SELECT salary FROM tb_logic

END52

Page 53: 第 17 章  Transact-SQL 结构化程序设计

IF语句3.使用嵌套的 IF语句嵌套可以在很大程度上拓展 IF语句的功能,使用嵌套可以编写更为复杂的条件判断语句。所谓嵌套,就是在 IF语句的语句或语句块中使用IF语句。使用嵌套时,最好使用 BEGIN END语句。

53

Page 54: 第 17 章  Transact-SQL 结构化程序设计

IF语句使用嵌套的 IF ELSE语句的语法结构如下:IF (条件 )

BEGINIF(条件 )

语句或语句块…

ENDELSE

BEGINIF (条件 )

语句或语句块…

END54

Page 55: 第 17 章  Transact-SQL 结构化程序设计

IF语句使用嵌套的 IF ELSE语句的执行方向判断起来较为复杂,但是在执行时根据嵌套层次依次去判断,就不会出现什么错误。USE database_demoGOINSERT INTO tb_logic VALUES(100)DECLARE @ret INT=99IF (@ret=100)BEGIN

INSERT INTO tb_logic VALUES(100)SELECT salary FROM tb_logic

ENDELSE

IF (@ret>90)BEGIN

UPDATE tb_logic SET salary=90 WHERE salary=100SELECT salary FROM tb_logic

END55

Page 56: 第 17 章  Transact-SQL 结构化程序设计

WHILE循环WHILE是 SQL Server中惟一的循环语句,用于重复执行语句或语句块。一般情况下,WHILE与 continue和 break配合使用。WHILE内的语句块被称为循环体。WHILE (条件 )

语句或语句块

WHILE的一个用途就是与游标配合。

56

Page 57: 第 17 章  Transact-SQL 结构化程序设计

WHILE循环USE database_demoGOINSERT INTO tb_logic VALUES(100)INSERT INTO tb_logic VALUES(99)GODECLARE tmp_cur CURSOR FOR

SELECT * FROM tb_logicOPEN tmp_curFETCH NEXT FROM tmp_curWHILE (@@FETCH_STATUS=0)

FETCH NEXT FROM tmp_curCLOSE tmp_curDEALLOCATE tmp_cur

57

Page 58: 第 17 章  Transact-SQL 结构化程序设计

其他语句除了上面介绍的那些主要控制流语句外, SQL Server还提供了一些其他的语句,主要为RETURN语句、 GOTO语句和WAITFOR语句。1. RETURN语句在结构化的程序中, SQL Server碰到RETURN语句后,将会认为该程序结束了, RETURN语句后面的语句都不会执行。

58

Page 59: 第 17 章  Transact-SQL 结构化程序设计

其他语句USE database_demoGOINSERT INTO tb_logic VALUES(100)GOSELECT salary FROM tb_logicRETURNINSERT INTO tb_logic VALUES(99)GOSELECT salary FROM tb_logic

显然, RETURN后的语句没有被执行。因为 SQL Server在执行到 RETURN后就终止了该 SQL语句组的执行。

59

Page 60: 第 17 章  Transact-SQL 结构化程序设计

其他语句2. GOTO语句GOTO语句是一个不推荐使用的语句,因为其不但会使结构化的程序难以理解,而且还会消耗更多的资源,建议用户尽量少用或不用GOTO语句。不过, GOTO语句有一个推荐的用处,就是用于将执行从深层嵌套的控制流语句中跳出。

显然, GOTO比 CONTINUE和 BREAK更好用。不过 GOTO语句需要和标签配合使用。标签是 GOTO语句跳到的目标。

60

Page 61: 第 17 章  Transact-SQL 结构化程序设计

其他语句GOTO语句的语法:标签 1:BEGIN

…GOTO 标签 1…

END

61

Page 62: 第 17 章  Transact-SQL 结构化程序设计

其他语句USE database_demoGOINSERT INTO tb_logic VALUES(100)GOGOTO label1INSERT INTO tb_logic VALUES(99)GOTOlabel1:SELECT salary FROM tb_logic

62

Page 63: 第 17 章  Transact-SQL 结构化程序设计

其他语句3.WAITFOR语句WAITFOR用于将执行暂停(即挂起),直到到达指定的时间或持续时间后继续执行。WAITFOR

DELAY ‘time_to_delay’| TIME ‘time_to_EXECUTE’

组成元素的意义:DELAY指示执行将挂起,要延迟一段时间后,再开始执行,最长可以为 24小时。time_to_delay是等待的时段,用 datetime表示,但不能含有日期信息。

63

Page 64: 第 17 章  Transact-SQL 结构化程序设计

其他语句TIME指示执行将被挂起,要等到指定的时间后,再开始执行。time_to_execute与 time_to_delay类似。

USE database_demoGOINSERT INTO tb_logic VALUES(100)GOSELECT salary,GETDATE() FROM tb_logicWAITFOR delay ‘00:00:10’SELECT salary,GETDATE() FROM tb_logic

64

Page 65: 第 17 章  Transact-SQL 结构化程序设计

其他语句4.系统存储过程 sp_executesql在执行字符串时,最好使用存储过程sp_executesql,而不是 EXECUTE语句。一方面,在安全上, EXECUTE语句更容易被人进行恶意的 SQL注入;另一方面, sp_executesql比 EXECUTE语句的功能更多、更有效率。

65

Page 66: 第 17 章  Transact-SQL 结构化程序设计

其他语句USE database_demoGOINSERT INTO tb_logic VALUES(100)INSERT INTO tb_logic VALUES(99)GODECLARE @salary_value INT=99DECLARE @SQL_str NCHAR(300)DECLARE @Pam_def NVARCHAR(100)=N’@salary INT’SET @SQL_str=‘SELECT salary FROM tb_logic WHERE salary=@salary’EXECUTE sp_executesql @SQL_str,@Pam_def,@salary=@salary_value

66

Page 67: 第 17 章  Transact-SQL 结构化程序设计

小结 本章重点介绍 T-SQL 语句结构化程序设计的

基本语法,包括 Transcat-SQL 的变量、常量、运算符、控制语句。这部分内容虽然简单,但是非常重要。因为只有灵活应用这些语法,才能设计出更高效、稳定的数据库程序。

67