返回首页

gbase数据、南大通用产品文档:GBase8sRETURN

更新日期:2024年09月11日

使用 RETURN 语句来指定 SPL 函数将哪些值(如果有的话)返回给调用上下
文。
语法

用法
在 GBase 8s 中,对于向后兼容性,您可以在 CREATE PROCEDURE 语句中使
用 RETURN 语句创建 SPL 函数。然而,通过在 CREATE FUNCTION 语句中

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1237
只使用 RETURN ,您可以保留使用 CREATE FUNCTION 来定义返回值的例程
的约定,并为其它例程保留 CREATE PROCEDURE。
SPL 函数中的所有 RETURN 语句必须和定义该函数的 CREATE FUNCTION
(或 CREATE PROCEDURE)语句的 RETURNING 子句相一致。表达式的任何
RETURN 列表在基数上必须与函数定义的 RETURNING 子句的数据类型的有序
列表相匹配,并且在数据类型方面必须与其兼容。
或者,即使 RETURNING 子句列出了一个或多个数据类型,RETURN 语句也不
能指定表达式。在这种情况下,没有指定表达式的 RETURN 语句等于将预期的
NULL 值的数目返回给调用上下文。只有将 SPL 函数声明为不返回任何值时,
不带有任何表达式的 RETURN 语句才可以存在。否则,它返回 NULL 值。
以下 SPL 函数有两个有效的 RETURN 语句:
CREATE FUNCTION two_returns (stockno INT) RETURNING CHAR (15);
DEFINE des CHAR(15);
ON EXCEPTION (-272) -- if user does not have select privilege
RETURN; -- return no values.
END EXCEPTION;
SELECT DISTINCT descript INTO des FROM stock
WHERE stock_num = stockno;
RETURN des;
END FUNCTION;
在前面的示例中调用函数的程序应测试是否没有返回值并进行相应的操作。
WITH RESUME 关键字
如果使用 WITH RESUME 关键字,则在执行 RETURN 语句后,SPL 函数的下
一个调用(对下一个 FETCH 或 FOREACH 语句)从跟随 RETURN 语句的语
句开始。任何执行 RETURN WITH RESUME 语句的函数必须在 FOREACH 循
环或 SELECT 的 FROM 子句中被调用。如果 SPL 例程执行 RETURN WITH
RESUME 语句,则 GBase 8s ESQL/C 应用程序中的 FETCH 语句可以调用 SPL
例程。
以下示例显示另一个 UDR 可调用的游标函数。在 RETURN WITH RESUME 语句将每
个值返回到调用的 UDR 或程序后,在下一次调用 series 时执行 series 的下一

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1238
行。如果变量 backwards 等于零(0),则没有值返回给调用的 UDR 或程序,并
停止 series 的执行:
CREATE FUNCTION series (limit INT, backwards INT) RETURNING INT;
DEFINE i INT;
FOR i IN (1 TO limit)
RETURN i WITH RESUME;
END FOR;
IF backwards = 0 THEN
RETURN;
END IF;
FOR i IN (limit TO 1 STEP -1)
RETURN i WITH RESUME;
END FOR;
END FUNCTION; -- series
从另一个数据库返回值
如果 SPL 函数使用 Return 子句从本地 GBase 8s 实例的另一个数据库返回值,
则支持将以下数据类型作为返回的数据类型:

不透明的内置数据类型

大多数内置透明数据类型,在跨数据库事务中的数据类型 中列出

以上两行中引用的内置类型的 DISTINCT

此列表中任何 DISTINCT 数据类型的 DISTINCT

显式转换为此列表中某个内置数据类型的任何不透明用户定义类型
(UDT)。
UDF 以及类型层次结构、转型、DISTINCT 类型和 UDT 的定义在每个参与数据
库中必须完全相同。相同的数据类型限制适用于外部函数从本地 GBase 8s 实例
的另一个数据库返回的值。有关跨同一数据库服务器的两个或多个数据库的分布
式操作中支持的数据类型的详细信息,请参阅跨数据库事务中的数据类型。
UDR 从另一个数据库服务器的表中只能返回以下数据类型:

任何不透明的内置数据类型

BOOLEAN

LVARCHAR

不透明数据类型 DISTINCT

GBase 8s SQL 指南:语法
南大通用数据技术股份有限公司 1239

BOOLEAN DISTINCT

LVARCHAR DISTINCT

此列表中出现的任何 DISTINCT 类型的 DISTINCT
只有在 DISTINCT 类型显式转换为内置类型时,UDR 才能从其它 GBase 8s 实
例的数据库返回这些 DISTINCT 类型。DISTINCT 数据类型的定义,它们的类型
层次结构,以及它们的强制转型在参与分布式操作的数据库中必须完全相同。对
于使用上一列表中的数据类型作为参数或返回数据类型的跨服务器 UDR 中的查
询或其它 DML 操作,必须在每个参与数据库中定义 UDR ,参与的 GBase 8s
实例必须支持数据类型为跨服务器操作中的返回值。
有关 GBase 8s 可在分布式操作中访问的数据类型的其它信息,请参阅分布式查
询中的数据类型。
外部函数和迭代器函数
在 SPL 程序中,如果外部函数不是迭代器函数,则可以使用 C 或 Java™ 语言
外部函数作为 RETURN 语句的表达式。迭代器函数是返回一行或多行数据的外
部函数(因而需要游标来执行)。
SPL 迭代函数必须包含 RETURN WITH RESUME 语句。有关在查询的 FROM
子句中通过虚拟表接口使用迭代器函数的信息,请参阅迭代器函数。

DBE_PLDEBUGGER 下系统函数用于单机下调试存储过程,目前支持的接口及其描述
如下所示。仅管理员有权限执行这些调试接口。
须知:当在函数体中创建用户时,
调用attach、
next、
continue、info_code、
step、
info_breakpoint、backtrace、finish 中会返回密码的明文。因此不建议用户在函数体中创建
用户。
对应权限角色为gs_role_pldebugger,可以由管理员用户通过如下命令将debugger 权限
赋权给该用户。
GRANT gs_role_pldebugger to user;
需要有两个客户端连接数据库,
一个客户端负责执行调试接口作为debug 端,
另一个客
户端执行调试函数,控制server 端存储过程执行。示例如下。

准备调试
通过PG_PROC,
查找到待调试存储过程的oid,
并执行DBE_PLDEBUGGER.turn_on(oid)。
本客户端就会作为server 端使用。
postgres=# CREATE OR REPLACE PROCEDURE test_debug ( IN
x INT)
AS
BEGIN
INSERT INTO t1 (a) VALUES (x);
DELETE FROM t1 WHERE a = x;
END;
/
CREATE PROCEDURE
postgres=# SELECT OID FROM PG_PROC WHERE PRONAME='test_debug';
oid
-------
16389
(1 row)

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1104
postgres=# SELECT * FROM DBE_PLDEBUGGER.turn_on(16389);
nodename | port
----------+------
datanode |
0
(1 row)

开始调试
server 端执行存储过程,会在存储过程内第一条SQL 语句前hang 住,等待debug 端发
送的调试消息。仅支持直接执行存储过程的调试,不支持通过trigger 调用执行的存储过程
调试。
postgres=# call test_debug(1);
再起一个客户端,作为debug 端,通过turn_on 返回的数据,调用
DBE_PLDEBUGGER.attach 关联到该存储过程上进行调试。
postgres=# SELECT * FROM DBE_PLDEBUGGER.attach('datanode',0);
funcoid |
funcname
| lineno |
query
---------+------------+--------+----------------------------------
16389 | test_debug |
3 |
INSERT INTO t1 (a) VALUES (x);
(1 row)
在执行attach 的客户端调试,执行下一条statement。
postgres=# SELECT * FROM DBE_PLDEBUGGER.next();
funcoid |
funcname
| lineno |
query
---------+------------+--------+----------------------
16389 | test_debug |
0 | [EXECUTION FINISHED]
(1 row)
在执行attach 的客户端调试,可以执行以下变量操作
postgres=# SELECT * FROM DBE_PLDEBUGGER.info_locals(); --打印全部变量
varname | vartype | value | package_name | isconst
---------+---------+-------+--------------+---------

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1105
x
| int4
| 1
|
| f
(1 row)
postgres=# SELECT * FROM DBE_PLDEBUGGER.set_var('x', 2); --变量赋值
set_var
---------
t
(1 row)
postgres=# SELECT * FROM DBE_PLDEBUGGER.print_var('x'); --打印单个变量
varname | vartype | value | package_name | isconst
---------+---------+-------+--------------+---------
x
| int4
| 2
|
| f
(1 row)
直接执行完成当前正在调试的存储过程。
postgres=# SELECT * FROM DBE_PLDEBUGGER.continue();
funcoid |
funcname
| lineno |
query
---------+------------+--------+----------------------
16389 | test_debug |
0 | [EXECUTION FINISHED]
(1 row)
直接退出当前正在调试的存储过程,不执行尚未执行的语句。
postgres=# SELECT * FROM DBE_PLDEBUGGER.abort();
abort
-------
t
(1 row)
client 端查看代码信息并识别可以设置断点行号。
postgres=# SELECT * FROM DBE_PLDEBUGGER.info_code(16389);
lineno |
query
| canbreak

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1106
--------+-----------------------------------------------------------+----------
| CREATE OR REPLACE PROCEDURE public.test_debug( IN
x INT) | f
1 | AS
DECLARE
| f
2 | BEGIN
| f
3 |
INSERT INTO t1 (a) VALUES (x);
| t
4 |
DELETE FROM t1 WHERE a = x;
| t
5 | END;
| f
6 | /
| f
(7 rows)
设置断点。
postgres=# SELECT * FROM DBE_PLDEBUGGER.add_breakpoint(16389,4);
lineno |
query
| canbreak
--------+-----------------------------------------------------------+----------
| CREATE OR REPLACE PROCEDURE public.test_debug( IN
x INT) | f
1 | AS
DECLARE
| f
2 | BEGIN
| f
3 |
INSERT INTO t1 (a) VALUES (x);
| t
4 |
DELETE FROM t1 WHERE a = x;
| t
5 | END;
| f
6 | /
| f
(7 rows)
查看断点信息。
postgres=# SELECT * FROM DBE_PLDEBUGGER.info_breakpoints();
breakpointno | funcoid | lineno |
query
| enable
--------------+---------+--------+---------------------------------+--------
0 |
16389 |
4 |
DELETE FROM t1 WHERE a = x; | t
(1 row)
执行至断点。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1107
postgres=# SELECT * FROM DBE_PLDEBUGGER.continue();
funcoid |
funcname
| lineno |
query
---------+------------+--------+---------------------------------
16389 | test_debug |
4 |
DELETE FROM t1 WHERE a = x;
(1 row)
存储过程执行结束后,调试会自动退出,再进行调试需要重新attach 关联。如果server
端不需要继续调试,可执行turn_off 关闭,或退出session。具体调试接口请见下面列表。
表DBE_PLDEBUGGER
接口名称
描述
DBE_PLDEBUGGER.turn_on
server 端调用,
标记存储过程可以调试,
调用后执行该存储
过程时会hang 住等待调试信息。
DBE_PLDEBUGGER.turn_of
f
server 端调用,标记存储过程关闭调试。
DBE_PLDEBUGGER.local_d
ebug_server_info
server 端调用,
打印本session 内所有已turn_on 的存储过程。
DBE_PLDEBUGGER.attach
debug 端调用,关联到正在调试存储过程。
DBE_PLDEBUGGER.info_lo
cals
debug 端调用,打印正在调试的存储过程中的变量当前值。
DBE_PLDEBUGGER.next
debug 端调用,单步执行。
DBE_PLDEBUGGER.continu
e
debug 端调用,继续执行,直到断点或存储过程结束。
DBE_PLDEBUGGER.abort
debug 端调用,停止调试,server 端报错长跳转。
DBE_PLDEBUGGER.print_v
ar
debug 端调用,
打印正在调试的存储过程中指定的变量当前
值。
DBE_PLDEBUGGER.info_co
de
debug 和server 端都可以调用,
打印指定存储过程的源语句
和各行对应的行号。
DBE_PLDEBUGGER.step
debug 端调用,单步进入执行。

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
1108
接口名称
描述
DBE_PLDEBUGGER.add_br
eakpoint
debug 端调用,新增断点。
DBE_PLDEBUGGER.delete_
breakpoint
debug 端调用,删除断点。
DBE_PLDEBUGGER.info_br
eakpoints
debug 端调用,查看当前的所有断点。
DBE_PLDEBUGGER.backtra
ce
debug 端调用,查看当前的调用栈。
DBE_PLDEBUGGER.enable_
breakpoint
debug 端调用,激活被禁用的断点。
DBE_PLDEBUGGER.disable
_breakpoint
debug 端调用,禁用已激活的断点。
DBE_PLDEBUGGER.finish
debug 端调用,继续调试,直到断点或返回上一层调用栈。
DBE_PLDEBUGGER.set_var
debug 端调用,为变量进行赋值操作。

kdestroy 工具为开源第三方提供,具体参数说明请参考Kerberos 官方文档:
https://web.mit.edu/kerberos/krb5-1.17/doc/user/user_commands/kdestroy.html?highlight=kdestro
y