Db2 SQL PL中的控制语句
我们知道,代码流程控制中,最常见的三种逻辑结构是顺序、选择、循环。
顺序就不用说了,我们重点看一下SQL PL中的选择和循环,以及其它流程控制语句。
环境
- 操作系统:Ubuntu 20.04
- Db2:11.5.0.0
选择
if
if
语句的逻辑结构为:
if ...... then......
elseif ...... then......
else......
end if
其中, elseif
和 else
是可选的。
注意: 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
语句通常与 leave
、 goto
、 iterate
、 return
一起使用。
创建文件 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
语句,一般我们都不会再用,不再赘述。
iterate
和 leave
类似Java里面的 continue
和 break
,前面有例子,不再赘述。
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
循环的例子。
此外,还可以声明变量 sqlcode
和 sqlstate
,当运行SQL PL语句时,Db2会自动把 sqlcode
和 sqlstate
赋值。
创建文件 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自动给变量 sqlcode
和 sqlstate
赋值了。
注意:
- 这两个变量名字是固定的,不能改变;
- 一旦访问了这两个变量,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中的控制语句相关推荐
- Db2 SQL PL简介
注:如果不熟悉Db2存储过程的基本概念和HelloWorld例子,请参考我另一篇文档( https://blog.csdn.net/duke_ding2/article/details/1248736 ...
- oracle绑定变量过多,oracle - 在SQL Plus中使用绑定变量并返回多行? - 堆栈内存溢出...
这是一个愚蠢的问题,但我似乎无法解决. 我有一个查询在OCI程序中引起麻烦,因此我想在SQL * Plus中手动运行它以检查是否有任何区别. 这是查询: select e.label as doc_n ...
- pl sql如何调试oracle存储过程,PL/SQL Developer中调试oracle的存储过程
作者:iamlaosong 唉,真土,之前用Toad,1直用dbms_output.put_line调试存储进程,只觉得不方便,用上PL/SQL Developer后,习惯性的还是用这个方法,人都是有 ...
- PL/SQL Developer中,存储过程无法调试的问题解决办法
在Oracle10中新建了一个用户,然后编写存储过程在PL/SQL Developer中调试,提示 ORA-0131: Insufficient privileges. Note: Debugging ...
- db2 删除schema中所有表_常用SQL系列之(六):删除方式、数据库、表及索引元信息查询等...
本系统为@牛旦教育IT课堂在微头条上的内容, 为便于查阅,特辑录于此,都是常用SQL基本用法.. 前两篇连接: (一):SQL点滴(查询篇):数据库基础查询案例实战 (二):SQL点滴(排序篇):数据 ...
- PL/SQL块中不能直接执行DDL语句(错误)
在PL/SQL块中不能直接执行DDL语句 (后篇批量删除表时却明明在PL/SQL块中使用了DROP,而且执行成功,厄...自打三十大板...谁来救我...) declare v_string ...
- oracle 12c pl/sql语言,ORACLE 12C SQL语句中通过with 定义PL/SQL 函数
在ORACLE 12C支持在sql语句中编写函数,用来实现sql语句操作需要使用函数的部分功能,该功能对于你不想在数据库中新建函数 or 你的库是read only模式下要使用新函数实现某种功能,可以 ...
- pl/sql 测试函数_如何在SQL单元测试中使用伪函数?
pl/sql 测试函数 In this article series, we are exploring SQL unit testing, in general, and also we are r ...
- 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 ...
最新文章
- 【SICP练习】136 练习3.67
- 串口 驱动 热敏打印机_菜鸟裹裹x 快麦打印机联合发布SC310,实现共享智能打印...
- 数据结构碎碎念(一)
- aix6.1 oracle12c,AIX6.1系统 oracle 11g数据库恢复过程
- ajax、jsonp简单封装
- XCTF_Web_新手练习区:get_post
- JS中 map, filter, some, every, forEach, for in, for of 用法总结
- 蓝桥杯基础模块3_2:数码管动态显示
- Shell脚本监控专线Network并SendEmail报警
- c语言空白字符的aci,c语言的保留字符有32个是那些啊???代表什么于是啊??...
- oracle中特殊字符处理
- Cortex-M3 (NXP LPC1788)之PWM(脉宽调制器)
- 四、Raid卡(阵列卡)
- PiFlow 朱小杰:科学家更爱开源 | Gitee 封面人物第 19 期
- 开了店铺没访客没流量?Shopee店铺日常运营引流方式来啦
- RealView® 编译工具 汇编器指南
- 2021-10-04
- java基础(多态的理解与应用)
- 突发!美国股市大跌,好戏才刚刚开始!(深度)
- Mermaid流程图