返回多个值

SPL 函数可从表的单个行返回多个值。下图展示从表的单个行返回两个列值的 SPL 函数。

图: 从表的单个行返回两个列值的 SPL 函数。

CREATE FUNCTION birth_date( num INTEGER )
            RETURNING VARCHAR(30), DATE;
            
            DEFINE n VARCHAR(30);
            DEFINE b DATE;
            
            SELECT name, bdate INTO n, b FROM emp_tab
            WHERE emp_no = num;
            RETURN n, b;
            
            END FUNCTION;

该函数从 emp_tab 表的一行将两个值(名和生日)返回给调用的例程。在此情况下,必须准备调用的例程来处理返回的 VARCHAR 和 DATE 值。

下图展示从多行返回多个值的 SPL 函数。

图: 从多行返回多个值的 SPL 函数。

CREATE FUNCTION birth_date_2( num INTEGER )
            RETURNING VARCHAR(30), DATE;
            DEFINE n VARCHAR(30);
            DEFINE b DATE;
            FOREACH cursor1 FOR
            SELECT name, bdate INTO n, b FROM emp_tab
            WHERE emp_no > num
            RETURN n, b WITH RESUME;
            END FOREACH;
            END FUNCTION;
在前图中,SELECT 语句从其员工编号大于用户输入的编号的行集访存两个值。满足该条件的行集可能包含一行、多行,或零行。由于 SELECT 语句可返回多行,因此将它放置在游标内。
提示: 当 SPL 例程内的语句未返回行时,为对应的 SPL 变量赋值 NULL。

RETURN 语句使用 WITH RESUME 关键字。当执行 RETURN WITH RESUME 时,将控制返回到调用的例程。但在下一次(通过 FETCH 或通过调用的例程中的游标的下一迭代)调用该 SPL 函数时,SPL 函数中的所有变量保持它们的相同的值,并从紧跟在 RETURN WITH RESUME 语句之后的语句继续执行。

如果您的 SPL 例程返回多个值,则调用的例程必须能够通过游标或循环来处理多个值,如下:
  • 如果调用的例程为 SPL 例程,则它需要 FOREACH 循环。
  • 如果调用的例程为 GBase 8s ESQL/C 程序,则它需要以 DECLARE 语句声明的游标。
  • 如果调用的例程为外部的例程,则它需要与编写该例程的语言相适应的游标或循环。
重要: 由 UDR 从本地服务器的外部数据库返回的值必须为内建的数据类型,或 UDT 显式地强制转型为内建的类型,或基于内建的类型的 DISTINCT 类型并显式地强制转型为内建的类型。此外,您必须定义 UDR 和参与的数据库中的所有强制转型。
下列是您可跨数据库执行的 SQL 操作的示例:
database db1;
            create table ltab1(lcol1 integer, lcol2 boolean, lcol3 lvarchar);
            insert into ltab1 values(1, 't', "test string 1");
            
            database db2;
            create table rtab1(r1col1 boolean, r1col2 blob, r1col3 integer)
            put r1col2 in (sbsp);
            create table rtab2(r2col1 lvarchar, r2col2 clob) put r2col2 in (sbsp);
            create table rtab3(r3col1 integer, r3col2 boolean,
            r3col3 lvarchar, r3col4 circle);
            
            create view rvw1 as select  * from rtab3; 
(该示例为跨数据库 Insert。)
database db1;
            create view lvw1 as select * from db2:rtab2;
            insert into db2:rtab1 values('t', 
            filetoblob('blobfile', 'client', 'db2:rtab1', 'r1col2'), 100);
            insert into db2:rtab2 values("inserted directly to rtab2",  
            filetoclob('clobfile', 'client', 'db2:rtab2', 'r2col2'));
            insert into db2:rtab3 (r3col1, r3col2, r3col3)
            select lcol1, lcol2, lcol3 from ltab1;
            insert into db2:rvw1 values(200, 'f', "inserted via rvw1");
            insert into lvw1 values ("inserted via lvw1", NULL);