当前位置:网站首页>Db2存储过程的屏幕输出,输出参数,返回结果集
Db2存储过程的屏幕输出,输出参数,返回结果集
2022-06-10 18:01:00 【蓝黑2020】
存储过程除了能够处理和运行业务逻辑,也能输出信息和返回结果。
- 屏幕输出:通过屏幕输出,显式的向用户展示数据,此外,在调试存储过程时也非常有用;
- 参数输出:通过
out参数,输出信息,可以通过屏幕展示,也可以被其它存储过程所访问; - 返回结果:隐式返回结果集,可以通过屏幕展示,也可以被其它存储过程所访问;
环境
- 操作系统:Ubuntu 20.04
- Db2:11.5.0.0
屏幕输出
可以通过调用 dbms_output 模块向“消息缓冲区”输出文本:
dbms_output.newline:类似于Java的System.out.println();dbms_output.put(xxx):类似于Java的System.out.print(xxx);dbms_output.putline(xxx):类似于Java的System.out.println(xxx);
注意:消息缓冲区默认并不是“标准输出”(也就是屏幕输出),所以,需要显式的指定一下:
set server output on:打开标准输出;set server output off:关闭标准输出;
注意:运行 dbms_output.put(xxx) 并不会立即输出文本到屏幕,只有后面的 dbms_output.newline 或者 dbms_output.putline(xxx) 才会导致其输出。
创建文件 test1.sql 如下:
set serveroutput on@
begin
call dbms_output.put_line('hello');
call dbms_output.put('world');
call dbms_output.put('OK');
call dbms_output.put_line('good');
call dbms_output.new_line();
call dbms_output.put_line('better');
end@
set serveroutput off@
运行脚本 test1.sql ,如下:
* temp0602 db2 -[email protected] -f test1.sql
DB20000I The SET SERVEROUTPUT command completed successfully.
DB20000I The SQL command completed successfully.
hello
worldOKgood
better
DB20000I The SET SERVEROUTPUT command completed successfully.
屏幕输出在调试脚本时非常方便。
参数输出
直接调用存储过程,打印其输出参数
创建文件 test2.sql 如下:
create or replace procedure myproc1(in p1 int, in p2 int, out p3 int)
begin
set p3 = p1 + p2;
end@
运行脚本 test2.sql 。
现在就可以调用 myproc1 了,out参数用 ? 占位:
* temp0602 db2 "call myproc1(100, 50, ?)"
Value of output parameters
--------------------------
Parameter Name : P3
Parameter Value : 150
Return Status = 0
在存储过程中访问另一个存储过程返回的输出参数
也可以在其它存储过程中调用 myproc1 。创建文件 test3.sql 如下:
set serveroutput on@
create or replace procedure myproc2()
begin
declare p1, p2, p3 int;
set p1 = 111;
set p2 = 6;
call myproc1(p1, p2, p3);
call dbms_output.put_line('p3 = ' || p3);
end@
call [email protected]
set serveroutput off@
运行脚本 test3.sql ,如下:
* temp0602 db2 -[email protected] -f test3.sql
DB20000I The SET SERVEROUTPUT command completed successfully.
DB20000I The SQL command completed successfully.
Return Status = 0
p3 = 117
DB20000I The SET SERVEROUTPUT command completed successfully.
注:如果是在其它存储过程中调用 myproc1 ,out参数就不能用 ? 占位了。
返回结果
存储过程不像函数,无法显式返回结果,不过存储过程可以隐式返回结果集。
直接调用存储过程,打印其返回的结果集
创建文件 test4.sql 如下:
create or replace procedure myproc3
begin
declare cur1 cursor with return for
select c1, c2 from t1;
open cur1;
end@
call [email protected]
运行脚本 test4.sql ,如下:
* temp0602 db2 -[email protected] -f test4.sql
DB20000I The SQL command completed successfully.
Result set 1
--------------
C1 C2
----------- -----------
1 111
2 222
3 333
3 record(s) selected.
Return Status = 0
一个存储过程可以返回多个结果集。创建文件 test5.sql 如下:
create or replace procedure myproc4
begin
declare cur1 cursor with return for
select c1, c2 from t1;
declare cur2 cursor with return for
select c1, c2 from t2;
open cur1;
open cur2;
end@
call [email protected]
运行脚本 test5.sql ,如下:
* temp0602 db2 -[email protected] -f test5.sql
DB20000I The SQL command completed successfully.
Result set 1
--------------
C1 C2
----------- -----------
1 111
2 222
3 333
3 record(s) selected.
Result set 2
--------------
C1 C2
----------- ----------
11 aaa
22 bbb
2 record(s) selected.
Return Status = 0
在定义存储过程时,可以指定返回结果集的最大个数。比如,创建文件 test6.sql 如下:
create or replace procedure myproc5
dynamic result sets 1
begin
declare cur1 cursor with return for
select c1, c2 from t1;
declare cur2 cursor with return for
select c1, c2 from t2;
open cur1;
open cur2;
end@
call [email protected]
运行脚本 test6.sql ,如下:
* temp0602 db2 -[email protected] -f test6.sql
DB20000I The SQL command completed successfully.
Result set 1
--------------
C1 C2
----------- -----------
1 111
2 222
3 333
3 record(s) selected.
Result set 2
--------------
C1 C2
----------- ----------
11 aaa
22 bbb
2 record(s) selected.
Return Status = 0
SQL0464W Procedure "DB2INST1.MYPROC5" returned "2" query result sets, which
exceeds the defined limit "1". SQLSTATE=0100E
* temp0602 echo $?
2
本例中,在存储过程里设置了 dynamic result sets 1 ,但是实际返回了2个结果集,所以运行时Db2给出了警告信息。
在存储过程中访问另一个存储过程返回的结果集
创建文件 test7.sql 如下:
create or replace procedure myproc6
dynamic result sets 2
begin
declare cur1 cursor with return for
select c1, c2 from t1;
declare cur2 cursor with return for
select c1, c2 from t2;
open cur1;
open cur2;
end@
create or replace procedure myproc7
begin
declare rs1, rs2 result_set_locator varying;
declare c1, c2 int default 0;
declare sqlcode, mysqlcode int default 0;
call myproc6;
associate result set locators(rs1, rs2) with procedure myproc6;
allocate ccur1 cursor for result set rs1;
repeat
fetch ccur1 into c1, c2;
set mysqlcode = sqlcode;
call dbms_output.put_line('c1 = ' || c1 || ', c2 = ' || c2);
until (mysqlcode <> 0)
end repeat;
close ccur1;
end@
set serveroutput on@
call [email protected]
set serveroutput off@
从本例可以看出,要想在存储过程中访问另一个存储过程返回的结果集,步骤如下:
declare rs1, rs2 result_set_locator varying:定义rs1和rs2这两个“结果集定位器”;call myproc6:调用存储过程;associate result set locators(rs1, rs2) with procedure myproc6:把rs1和rs2关联到存储过程;allocate ccur1 cursor for result set rs1:给结果集分配游标,注意这里的游标变量不能提前定义,也不能显式open游标;fetch ccur1 into c1, c2:获取结果集的内容;
运行脚本 test7.sql ,如下:
* temp0602 db2 -[email protected] -f test7.sql
DB20000I The SQL command completed successfully.
DB20000I The SQL command completed successfully.
DB20000I The SET SERVEROUTPUT command completed successfully.
Return Status = 0
c1 = 1, c2 = 111
c1 = 2, c2 = 222
c1 = 3, c2 = 333
c1 = 3, c2 = 333
DB20000I The SET SERVEROUTPUT command completed successfully.
注意: ccur1 虽然是游标,但是不能通过 ccur1 is found 来判断是否fetch到数据,会报错-206,不明白是为什么。只好换成一个土办法,就是判断fetch的sqlcode是不是0,如果不是0,就说明fetch没成功。
参考
- 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 (中文版)
边栏推荐
- c语言---14 循环语句for
- TSMC liudeyin: do not worry about semiconductor inventory correction and cooperation between the United States, Japan and South Korea. This year's performance will increase by 30%!
- [QNX hypervisor 2.2 user manual] 3.3 configure guest
- AGI基础,不确定性推理,主观逻辑一书ppt2
- After the qtmqtt source code compilation is set to keepalive, the Ping package timeout error does not return a problem repair (qmqtt:: mqttnopingresponse, qmqtt:: clientprivate:: onpingtimeo)
- 低碳数据中心建设思路及未来趋势
- 完全背包问题以及优化小技巧
- 阅读micropyton源码-添加C扩展类模块(1)
- Real time business intelligence Bi (II): reasonable ETL architecture design to realize quasi real time Business Intelligence BI
- 套路解---马走棋盘问题
猜你喜欢

企业数据质量管理:如何进行数据质量评估?

Postman interface test tool

c语言---12 分支语句switch

Research on next generation distributed file system

Stream生成的3张方式-Lambda

当前有哪些主流的全光技术方案?-下篇

AFL fuzzy multithreading

数据处理时代,数据分析成为基础建设

C language -- 13 loop statement while

Uniapp native JS to convert the Gregorian calendar to the lunar calendar
随机推荐
优惠券的工厂与策略模式实现方案
NaturalSpeech模型合成语音在CMOS测试中首次达到真人语音水平
Developers changing the world - Yao Guang teenagers playing Tetris
MySQL索引失效场景
光储直柔配电系统浅析
flutter系列之:UI layout简介
The value of Business Intelligence BI. Is visual report equal to Business Intelligence BI?
IBOX系统开发核心功能和部分核心源码
用基础比率重写清晰的贝叶斯公式
数字化时代,企业为什么要做数字化转型?
c语言---8 初识常见关键字
数据的软删除—什么时候需要?又如何去实现?
企业管理者的质疑,这么多年的信息化,我们的钱花哪去了?
QtMqtt 源码编译设置KeepAlive后ping包超时错误不返回问题修复(QMQTT::MqttNoPingResponse,QMQTT::ClientPrivate::onPingTimeo)
vcsa7u3c安装教程
Wireshark学习笔记(一)常用功能案例和技巧
VMware ESXi 各版本号对照表
&& 与 ||
C语言在底层如何对double和float压栈
AGI基础,不确定性推理,主观逻辑一书ppt1