iSeries:SQLRPGLE 如何为 SELECT 语句中的每条记录调用过程
iSeries: SQLRPGLE How to call a procedure for each record in a SELECT statement
在 SQLRPGLE 程序中,我需要 运行 插入语句以将一些记录复制到另一个已复制记录并分配了新记录 ID 的文件。
为此,我遵循了以下步骤:
1) 制作一个程序原型,每次调用时获取一个新的记录 ID
D ri_box12 PR 13S 0
D wkFileName 10A Value
2)执行动态SQL语句
C EVAL SQL_STM='insert into PGMR46/STD05GR0F'
C +' (select CART, CARV, '
C +%char(ri_box12('STD05GR0F'))
C +' from arasso0f)'
C/EXEC SQL
C+ execute immediate :SQL_STM
C/END-EXEC
3) 定义ri_box12过程
P ri_box12 B
D ri_box12 PI 13S 0
D wkFileName 10A Value
D wkID S 13S 0
C DO
** ...some instructions to give wkID a value
C ENDDO
C Return wkID
P E
关键是 ri_box12 只被调用一次,所以所有复制的记录都有相同的 ID;程序的多个 运行 再次复制具有新记录 ID 的所有记录。
我做错了什么或者我错过了什么?
比你厉害
首先,您不需要在这里使用动态 SQL。静态 SQL 可以工作,出于安全和性能原因,首选静态 SQL。
/free
exec SQL
insert into PGMR46/STD05GR0F
select CART, CARV, ri_box12('STD05GR0F')
from arasso0f
end-exec;
但是,为了使 RPGLE 函数的 CALL 起作用,您缺少了一件。
您必须定义所谓的外部用户定义函数 (UDF)。这是一次性步骤。您基本上是在通知 SQL 查询引擎 RPGLE 函数存在以及它的界面是什么样的。
您通常不希望在与 ri_box12()
函数相同的程序中使用上面的 INSERT
语句。通常你会有这样的过程
- 创建包含 ri_box12()
的 *SRVPGM(或 *PGM)
- 创建指向 ri_box12() 的 UDF
- 创建 program/stored 使用 UDF 的过程
第 3 步是包含您的 INSERT
SQL 语句的程序。
第 2 步只是 运行 一个 SQL 语句,如下所示:
create function ri_box12(
filename char(10)
) returns numeric(13,0)
language RPGLE
parameter style general
returns null on null input
program type sub
external name 'MYSRVPGM(RIBOX_12)';
您 can/should 还为函数指定了许多其他设置。查看 SQL 参考手册的 CREATE FUNCTION (External Scalar) 部分。
我还强烈推荐阅读 External Procedures, Triggers, and User-Defined Functions on IBM DB2 for i Redbook
不确定 OP 中的函数 ri_box12 是做什么的,但如果只是一个序列号,那么 SQL SEQUENCE 可能是实现该效果的方法;有关示例,请参见以下脚本 SQL:
drop table qtemp.nbrs ;
drop table qtemp.junk ;
drop sequence myseq ;
create table qtemp.nbrs (n int) ;
insert into qtemp.nbrs values(10), (20), (30) ;
create table qtemp.junk (s int, i int) ;
create sequence myseq as integer start with 1 ;
insert into qtemp.junk
select next value for myseq, n from qtemp.nbrs ;
select * from qtemp.junk
; -- report from the above SELECT query follows:
S I
1 10
2 20
3 30
IBM i 7.2->Database->Reference->SQL reference->Concepts->Sequences
IBM i 7.2->Database->Reference->SQL reference->Statements->CREATE SEQUENCE
IBM i 7.2->Database->Reference->SQL reference->Language elements->Expressions->Sequence reference
在 SQLRPGLE 程序中,我需要 运行 插入语句以将一些记录复制到另一个已复制记录并分配了新记录 ID 的文件。 为此,我遵循了以下步骤:
1) 制作一个程序原型,每次调用时获取一个新的记录 ID
D ri_box12 PR 13S 0 D wkFileName 10A Value2)执行动态SQL语句
C EVAL SQL_STM='insert into PGMR46/STD05GR0F' C +' (select CART, CARV, ' C +%char(ri_box12('STD05GR0F')) C +' from arasso0f)' C/EXEC SQL C+ execute immediate :SQL_STM C/END-EXEC3) 定义ri_box12过程
P ri_box12 B D ri_box12 PI 13S 0 D wkFileName 10A Value D wkID S 13S 0 C DO关键是 ri_box12 只被调用一次,所以所有复制的记录都有相同的 ID;程序的多个 运行 再次复制具有新记录 ID 的所有记录。
** ...some instructions to give wkID a value C ENDDO C Return wkID P E
我做错了什么或者我错过了什么?
比你厉害
首先,您不需要在这里使用动态 SQL。静态 SQL 可以工作,出于安全和性能原因,首选静态 SQL。
/free
exec SQL
insert into PGMR46/STD05GR0F
select CART, CARV, ri_box12('STD05GR0F')
from arasso0f
end-exec;
但是,为了使 RPGLE 函数的 CALL 起作用,您缺少了一件。
您必须定义所谓的外部用户定义函数 (UDF)。这是一次性步骤。您基本上是在通知 SQL 查询引擎 RPGLE 函数存在以及它的界面是什么样的。
您通常不希望在与 ri_box12()
函数相同的程序中使用上面的 INSERT
语句。通常你会有这样的过程
- 创建包含 ri_box12() 的 *SRVPGM(或 *PGM)
- 创建指向 ri_box12() 的 UDF
- 创建 program/stored 使用 UDF 的过程
第 3 步是包含您的 INSERT
SQL 语句的程序。
第 2 步只是 运行 一个 SQL 语句,如下所示:
create function ri_box12(
filename char(10)
) returns numeric(13,0)
language RPGLE
parameter style general
returns null on null input
program type sub
external name 'MYSRVPGM(RIBOX_12)';
您 can/should 还为函数指定了许多其他设置。查看 SQL 参考手册的 CREATE FUNCTION (External Scalar) 部分。
我还强烈推荐阅读 External Procedures, Triggers, and User-Defined Functions on IBM DB2 for i Redbook
不确定 OP 中的函数 ri_box12 是做什么的,但如果只是一个序列号,那么 SQL SEQUENCE 可能是实现该效果的方法;有关示例,请参见以下脚本 SQL:
drop table qtemp.nbrs ;
drop table qtemp.junk ;
drop sequence myseq ;
create table qtemp.nbrs (n int) ;
insert into qtemp.nbrs values(10), (20), (30) ;
create table qtemp.junk (s int, i int) ;
create sequence myseq as integer start with 1 ;
insert into qtemp.junk
select next value for myseq, n from qtemp.nbrs ;
select * from qtemp.junk
; -- report from the above SELECT query follows:
S I
1 10
2 20
3 30
IBM i 7.2->Database->Reference->SQL reference->Concepts->Sequences
IBM i 7.2->Database->Reference->SQL reference->Statements->CREATE SEQUENCE
IBM i 7.2->Database->Reference->SQL reference->Language elements->Expressions->Sequence reference