我们知道,代码流程控制中,最常见的三种逻辑结构是顺序、选择、循环。

顺序就不用说了,我们重点看一下SQL PL中的选择和循环,以及其它流程控制语句。

环境

  • 操作系统:Ubuntu 20.04
  • Db2:11.5.0.0

选择

if

if 语句的逻辑结构为:

if ...... then......
elseif ...... then......
else......
end if

其中, elseifelse 是可选的。

注意: elseif 是一个关键字,不要分开。

case

case 语句有两种用法:

  • case 处一个值, when 处一个值,判断二者是否相等:
case ......when ...... then......when ...... then......else......
end case
  • case 处为空, when 处为一个判断,看其是否为true:
casewhen ...... then......when ...... then......else......
end case

这两种case的用法其实跟SQL语句里的case非常相似,只不过SQL里的case是表达式,这里的case是语句。

循环

for

创建文件 test1.sql 如下:

set serveroutput on@beginfor v as cur1 cursor forselect firstnme, lastname from employeedocall dbms_output.put_line(firstnme || ', ' || lastname);end for;
end@set serveroutput off@

运行脚本 test1.sql ,如下:

➜  temp0530 db2 -td@ -f test1.sql
DB20000I  The SET SERVEROUTPUT command completed successfully.DB20000I  The SQL command completed successfully.CHRISTINE, HAAS
MICHAEL, THOMPSON
SALLY, KWAN
JOHN, GEYER
IRVING, STERN
EVA, PULASKI
EILEEN, HENDERSON
THEODORE, SPENSER
VINCENZO, LUCCHESSI
SEAN, O'CONNELL
DELORES, QUINTANA
HEATHER, NICHOLLS
BRUCE, ADAMSON
ELIZABETH, PIANKA
MASATOSHI, YOSHIMURA
MARILYN, SCOUTTEN
JAMES, WALKER
DAVID, BROWN
WILLIAM, JONES
JENNIFER, LUTZ
JAMES, JEFFERSON
SALVATORE, MARINO
DANIEL, SMITH
SYBIL, JOHNSON
MARIA, PEREZ
ETHEL, SCHNEIDER
JOHN, PARKER
PHILIP, SMITH
MAUDE, SETRIGHT
RAMLAL, MEHTA
WING, LEE
JASON, GOUNOT
DIAN, HEMMINGER
GREG, ORLANDO
KIM, NATZ
KIYOSHI, YAMAMOTO
REBA, JOHN
ROBERT, MONTEVERDE
EILEEN, SCHWARTZ
MICHELLE, SPRINGER
HELENA, WONG
ROY, ALONZODB20000I  The SET SERVEROUTPUT command completed successfully.

loop

loop 语句通常与 leavegotoiteratereturn 一起使用。

创建文件 test2.sql 如下:

set serveroutput on@begindeclare v_deptno char(3);declare v_deptname varchar(29);declare at_end int default 0;declare not_found condition for sqlstate '02000';declare c1 cursor forselect deptno, deptname from department order by deptno;declare continue handler for not_found set at_end = 1;open c1;myloop: loopfetch c1 into v_deptno, v_deptname;if at_end = 1 thenleave myloop;elseif v_deptno = 'D11' theniterate myloop;end if;call dbms_output.put_line(v_deptno || ', ' || v_deptname);end loop;close c1;
end@set serveroutput off@

运行脚本 test2.sql ,如下:

➜  temp0530 db2 -td@ -f test2.sql
DB20000I  The SET SERVEROUTPUT command completed successfully.DB20000I  The SQL command completed successfully.A00, SPIFFY COMPUTER SERVICE DIV.
B01, PLANNING
C01, INFORMATION CENTER
D01, DEVELOPMENT CENTER
D21, ADMINISTRATION SYSTEMS
E01, SUPPORT SERVICES
E11, OPERATIONS
E21, SOFTWARE SUPPORT
F22, BRANCH OFFICE F2
G22, BRANCH OFFICE G2
H22, BRANCH OFFICE H2
I22, BRANCH OFFICE I2
J22, BRANCH OFFICE J2DB20000I  The SET SERVEROUTPUT command completed successfully.

由于 loop 循环没有结束条件,这种循环的做法似乎比较麻烦。

while

while (......) do......
end while

具体参见我另一篇文档(https://blog.csdn.net/duke_ding2/article/details/125012716)里数组元素求和的例子。

repeat

repeat 循环与 while 循环的区别在于,前者是先做再判断,后者是先判断再做,所以 repeat 循环至少会迭代一次。

repeat......
until (......)
end repeat

其它流程控制语句

goto

臭名昭著的 goto 语句,一般我们都不会再用,不再赘述。

iterateleave

类似Java里面的 continuebreak ,前面有例子,不再赘述。

return

直接返回,与其它语言如Java里的 return 类似,可以直接在循环内部返回。

创建文件 test8.sql 如下:

set serveroutput on@begindeclare n, i int;set n = 10;set i = 1;while (i <= n) doif (i < 5) thencall dbms_output.put_line('hi, ' || i);elseif (i < 7) thenreturn;elsecall dbms_output.put_line('OK, ' || i);end if;set i = i + 1;end while;
end@set serveroutput off@

运行脚本 test8.sql ,如下:

➜  temp0530 db2 -td@ -f test8.sql
DB20000I  The SET SERVEROUTPUT command completed successfully.DB20000I  The SQL command completed successfully.hi, 1
hi, 2
hi, 3
hi, 4DB20000I  The SET SERVEROUTPUT command completed successfully.

条件处理

有点类似于其它语言如Java中的异常处理。

当程序出现sqlexceptin、sqlwarning、not found时,如果有对应的handler,就会运行handler的代码逻辑。参见上面 loop 循环的例子。

此外,还可以声明变量 sqlcodesqlstate ,当运行SQL PL语句时,Db2会自动把 sqlcodesqlstate 赋值。

创建文件 test3.sql 如下:

call sysproc.admin_cmd('reorg table xxx')@

假设表 xxx 不存在,则运行脚本 test3.sql ,如下:

➜  temp0530 db2 -td@ -f test3.sql
SQL2211N  The specified table does not exist.  SQLSTATE=01H52

可见,对于reorg操作,如果表不存在,则sqlcode是 -2211 ,sqlstate是 01H52

创建文件 test4.sql 如下:

set serveroutput on@begindeclare sqlcode int default 0;declare sqlstate char(5 octets) default '00000';call sysproc.admin_cmd('reorg table xxx');call dbms_output.put_line('sqlcode = ' || sqlcode || ', sqlstate = ' || sqlstate);call dbms_output.put_line('sqlcode = ' || sqlcode || ', sqlstate = ' || sqlstate);
end@set serveroutput off@

假设表 xxx 不存在,则运行脚本 test4.sql ,如下:

➜  temp0530 db2 -td@ -f test4.sql
DB20000I  The SET SERVEROUTPUT command completed successfully.DB20000I  The SQL command completed successfully.sqlcode = -2211, sqlstate = 01H52
sqlcode = 0, sqlstate = 00000DB20000I  The SET SERVEROUTPUT command completed successfully.

可见,Db2自动给变量 sqlcodesqlstate 赋值了。

注意:

  • 这两个变量名字是固定的,不能改变;
  • 一旦访问了这两个变量,Db2就会隐式的将其值重置(所以最好把其值赋给其它变量,以便使用);

创建文件 test5.sql 如下:

set serveroutput on@begindeclare sqlcode int default 0;declare sqlstate char(5 octets) default '00000';declare not_found condition for sqlstate '01H52';declare continue handler for not_foundcall dbms_output.put_line('not found. sqlcode = ' || sqlcode || ', sqlstate = ' || sqlstate);call sysproc.admin_cmd('reorg table xxx');call dbms_output.put_line('sqlcode = ' || sqlcode || ', sqlstate = ' || sqlstate);call dbms_output.put_line('sqlcode = ' || sqlcode || ', sqlstate = ' || sqlstate);
end@set serveroutput off@

假设表 xxx 不存在,则运行脚本 test5.sql ,如下:

➜  temp0530 db2 -td@ -f test5.sql
DB20000I  The SET SERVEROUTPUT command completed successfully.DB20000I  The SQL command completed successfully.not found. sqlcode = -2211, sqlstate = 01H52
sqlcode = 0, sqlstate = 00000
sqlcode = 0, sqlstate = 00000DB20000I  The SET SERVEROUTPUT command completed successfully.

可见,如果声明了合适的条件处理,当满足条件时(本例中sqlstate为 01H52 ),就会运行相应的handler处理逻辑。

参考

  • https://www.ibm.com/docs/en/db2/11.5?topic=data-developing-routines
  • https://www.ibm.com/docs/zh/db2/11.5?topic=data-developing-routines (中文版)

Db2 SQL PL中的控制语句相关推荐

  1. Db2 SQL PL简介

    注:如果不熟悉Db2存储过程的基本概念和HelloWorld例子,请参考我另一篇文档( https://blog.csdn.net/duke_ding2/article/details/1248736 ...

  2. oracle绑定变量过多,oracle - 在SQL Plus中使用绑定变量并返回多行? - 堆栈内存溢出...

    这是一个愚蠢的问题,但我似乎无法解决. 我有一个查询在OCI程序中引起麻烦,因此我想在SQL * Plus中手动运行它以检查是否有任何区别. 这是查询: select e.label as doc_n ...

  3. pl sql如何调试oracle存储过程,PL/SQL Developer中调试oracle的存储过程

    作者:iamlaosong 唉,真土,之前用Toad,1直用dbms_output.put_line调试存储进程,只觉得不方便,用上PL/SQL Developer后,习惯性的还是用这个方法,人都是有 ...

  4. PL/SQL Developer中,存储过程无法调试的问题解决办法

    在Oracle10中新建了一个用户,然后编写存储过程在PL/SQL Developer中调试,提示 ORA-0131: Insufficient privileges. Note: Debugging ...

  5. db2 删除schema中所有表_常用SQL系列之(六):删除方式、数据库、表及索引元信息查询等...

    本系统为@牛旦教育IT课堂在微头条上的内容, 为便于查阅,特辑录于此,都是常用SQL基本用法.. 前两篇连接: (一):SQL点滴(查询篇):数据库基础查询案例实战 (二):SQL点滴(排序篇):数据 ...

  6. PL/SQL块中不能直接执行DDL语句(错误)

    在PL/SQL块中不能直接执行DDL语句 (后篇批量删除表时却明明在PL/SQL块中使用了DROP,而且执行成功,厄...自打三十大板...谁来救我...) declare     v_string  ...

  7. oracle 12c pl/sql语言,ORACLE 12C SQL语句中通过with 定义PL/SQL 函数

    在ORACLE 12C支持在sql语句中编写函数,用来实现sql语句操作需要使用函数的部分功能,该功能对于你不想在数据库中新建函数 or 你的库是read only模式下要使用新函数实现某种功能,可以 ...

  8. pl/sql 测试函数_如何在SQL单元测试中使用伪函数?

    pl/sql 测试函数 In this article series, we are exploring SQL unit testing, in general, and also we are r ...

  9. t–sql pl–sql_SQL Server –在T-SQL中使用最低的度量单位

    t–sql pl–sql A client recently discovered a discrepancy on one of our reports that showed an improve ...

最新文章

  1. 【SICP练习】136 练习3.67
  2. 串口 驱动 热敏打印机_菜鸟裹裹x 快麦打印机联合发布SC310,实现共享智能打印...
  3. 数据结构碎碎念(一)
  4. aix6.1 oracle12c,AIX6.1系统 oracle 11g数据库恢复过程
  5. ajax、jsonp简单封装
  6. XCTF_Web_新手练习区:get_post
  7. JS中 map, filter, some, every, forEach, for in, for of 用法总结
  8. 蓝桥杯基础模块3_2:数码管动态显示
  9. Shell脚本监控专线Network并SendEmail报警
  10. c语言空白字符的aci,c语言的保留字符有32个是那些啊???代表什么于是啊??...
  11. oracle中特殊字符处理
  12. Cortex-M3 (NXP LPC1788)之PWM(脉宽调制器)
  13. 四、Raid卡(阵列卡)
  14. PiFlow 朱小杰:科学家更爱开源 | Gitee 封面人物第 19 期
  15. 开了店铺没访客没流量?Shopee店铺日常运营引流方式来啦
  16. RealView® 编译工具 汇编器指南
  17. 2021-10-04
  18. java基础(多态的理解与应用)
  19. 突发!美国股市大跌,好戏才刚刚开始!(深度)
  20. Mermaid流程图

热门文章

  1. 游戏开发中的复杂度与银弹
  2. vue侧边栏组件_画布侧边栏Vue组件
  3. 圭尔夫大学计算机科学硕士,加拿大硕士生物医学专业介绍:圭尔夫大学
  4. 2023年全国最新二级建造师精选真题及答案14
  5. Liunx操作-Record20—MMAP共享映射区相关的操作
  6. PDF转成JPG,使用PDFTOJPG并去除水印
  7. 使用html2canvas和jspdf把网页保存pdf并下载
  8. pdf转图片的两种方式(java)
  9. 有个这样的程序猿男友你是否愿意嫁给他呢?
  10. [MATLAB] 读取ASII文件中的复数数据