返回首页

gbase数据、南大通用产品文档:GBase8s管理 sqlda 结构

更新日期:2024年09月11日

您的 GBase 8s ESQL/C 程序可以下表总结的 SQL 语句来操纵 sqlda 结构。

表 22. 可用于操纵 sqlda 结构的 SQL 语句
SQL 语句
用途
请参阅
DESCRIBE...INTO
分配 sqlda 结构,并以关于列列表列的信
息初始化该结构
为 sqlda
结构分配内

初始化
sqlda 结构



表 23. 可用于操纵 sqlda 结构的 SQL 语句:使用游标的 SELECT 和 EXECUTE FUNCTION 语句
SQL 语句
用途
请参阅
OPEN...USING
DESCRIPTOR
FETCH...USING
DESCRIPTOR

从指定的 sqlda 结构取得任何输入参数
将该行的内容放至 sqlda 结构内

指定输入参
数值
将列值放至
sqlda 结构




表 24. 可用于操纵 sqlda 结构的 SQL 语句:仅返回一行的 SELECT 和 EXECUTE FUNCTION 语句
SQL 语句
用途
请参阅
EXECUTE...INTO
DESCRIPTOR
将该单个行的内容放至 sqlda 结构内
将列值放至
sqlda 结构



表 25. 可用于操纵 sqlda 结构的 SQL 语句:非 SELECT 语句
SQL 语句
用途
请参阅
EXECUTE...USING
DESCRIPTOR
从指定的 sqlda 结构取得任何输入信息
指定输入参
数值


表 26. 可用于操纵 sqlda 结构的 SQL 语句:使用插入游标的 INSERT 语句

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 567 -

SQL 语句
用途
请参阅
PUT...USING
DESCRIPTOR
在它从指定的 sqlda 结构获得列值之后,
将一行放至插入缓冲区内
处理未知的
列列表

此外,您的 GBase 8s ESQL/C 程序可以下列方式管理 sqlda 结构:
声明一个指向sqlda 结构的变量指针。
将值指定给 sqlda 字段来以丢失的列信息提供数据库服务器。
从 sqlda 字段取得信息来访问从数据库服务器接收的列信息。
释放分配给 sqlda 结构的内存,当以它停止您的程序时。
定义 sqlda 结构
GBase 8s ESQL/Csqlda.h 头文件定义 sqlda 结构。

要定义 sqlda 结构,GBase 8s ESQL/C 程序必须采取下列行动:
包括 sqlda.h 头文件来在您的程序中为 sqlda 提供声明
GBase 8s ESQL/C 预处理器自动地包括 sqlhdr.h 文件,其包括 sqlda.h 头文件。

声明变量名称作为指向 sqlda 结构的指针
下列代码行声明 da_ptr 变量作为 sqlda 指针:
struct sqlda *da_ptr;

重要: 指向 sqlda 结构的指针不是 GBase 8s ESQL/C 主变量。因此,您不需要以关
键字 EXEC SQL 或美元
($)
符号先于该语句声明。
此外,
在该程序会中,
您不以冒号
(:)
或美元($)符号先于任何对指针的引用。
为 sqlda 结构分配内存
在您定义主变量作为指向 sqlda 结构的指针之后,
您必须确保为此结构的所有部分分
配内存,如下:
要为 sqlda 结构自身分配内存,请使用 DESCRIBE...INTO 语句。
下列 DESCRIBE 语句获得关于准备好的语句 st_id 的信息,
为 sqlda 结构分配内存,
并将 sqlda 结构的地址放至指针 da_ptr 中:
EXEC SQL describe st_id into da_ptr;

要为 sqlvar_struct 结构分配内存,请采取下列行动:

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 568 -

如果该准备好的语句是 SELECT(不带有 INTO TEMP 子句)、INSERT 或
EXECUTE FUNCTION 语句,
则 DESCRIBE...INTO 语句可为 sqlvar_struct 结构分配空间。

如果准备了某些其他 SQL 语句,且您想要在数据库服务器中发送或接收列,则您的
程序必须为 sqlvar_struct 结构分配空间。
要为 sqldata 字段的数据分配内存,请确保该数据类型与正确的词边界一致。

如果您使用 sqlda 结构来定义输入参数,则您不可使用 DESCRIBE 语句。因此,您
的程序必须显式地同时为 sqlda 结构和 sqlvar_struct 结构分配内存。
初始化 sqlda 结构
要发送或接收数据库中的列值,
您的 GBase 8s ESQL/C 程序必须初始化 sqlda 结构,
以便于它描述该准备好的语句的未知的列。

要初始化 sqlda 结构,您必须执行下列步骤:
将 sqlvar 字段设置为初始化的 sqlvar_struct 结构的地址。
设置 sqld 字段来指示未知的列数(以及相关联的 sqlvar_struct 结构)。

除了为 sqlda 结构分配内存,DESCRIBE...INTO 语句还以关于该准备好的
语句的信息初始化此结构。DESCRIBE...INTO 可提供的信息,依赖于它已描述
了哪个 SQL 语句。

如果准备好的语句是 SELECT
(不带有 INTO TEMP 子句)

INSERT 或 EXECUTE
FUNCTION 语句,则 DESCRIBE...INTO 语句可确定关于列列表中列的信息。因此,
DESCRIBE...INTO 语句采取下列行动来初始化 sqlda 结构:
它为 sqlda 结构分配内存。
它设置 sqlda.sqld 字段,其包含以数据初始化了的 sqlvar_struct 结构的数目。此值为
列列表中的列和表达式的数目(SELECT 和 INSERT),或返回的值的数目(EXECUTE
FUNCTION)。
它为组件 sqlvar_struct 结构分配内存,
对于列列表中的每一列或表达式
(SELECT 和
INSERT)

或对于每一返回的值
(EXECUTE FUNCTION)

对应一个 sqlvar_struct 结构。
它将 sqlda.sqlvar 字段设置为 DESCRIBE 为该 sqlvar_struct 结构分配的内存的初始
地址。
它描述在准备好的 SELECT(不带有 INTO TEMP)、EXECUTE FUNCTION 或
INSERT 语句中每一未知的列。
DESCRIBE...INTO 语句为每一列初始化 sqlvar_struct 结构
的字段,如下:
它初始化 sqltype、sqllen 和 sqlname 字段(对于 CHAR 类型数据,或对于

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 569 -

DATETIME 或 INTERVAL 数据的限定符),来提供关于该列的来自数据库的信息。
对于大多数数据类型,sqllen 字段保存以字节计的该列的长度。如果该列为集合类型
(SET、
MULTISET 或 LIST)

row 类型
(命名的或未命名的)
或 opaque 类型,
则 sqllen
字段为零。

它将 sqldata 和 sqlind 字段初始化为空。

重要: 不像系统描述符区域那样,带有 sqlda 指针的 DESCRIBE 不为列数据
(sqldata 字段)分配内存。在您的程序从数据库服务器收到列值之前,它必须分配此数据
空间。

DESCRIBE 语句提供关于列列表的列的信息。因此,您通常在准备好了
SELECT(不带有 INTO
TEMP 子句)、INSERT 或 EXECUTE
FUNCTION 语句之后,
使用 DESCRIBE...INTO。DESCRIBE...INTO 语句不仅初始化 sqlda 结构,而且
返回准备好的 SQL 语句的类型。

下列 DESCRIBE 语句还为一个 sqlda 结构和为两个 sqlvar_struct 数据结构(一个
为 customer_num 列,另一个为 company 列)分配内存,然后,以分配给 sqlvar_struct
结构的内存的初始地址来初始化指针 da_ptr->sqlvar:
EXEC SQL prepare st_id
'select customer_num, company from customer
where customer_num = ?';
EXEC SQL describe st_id into da_ptr;

前面的 DESCRIBE...INTO 语句返回 SQLCODE 值 0,来指示该准备好的语句为
SELECT 语句。

下图展示此 DESCRIBE...INTO 语句可以初始化的样例 sqlda 结构。

图 5. 两列的样例 sqlda 结构

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 570 -




如果准备好了某其他 SQL 语句,
则该 DESCRIBE...INTO 语句不可初始化 sqlda 结
构。要发送或接收该数据库中的列值,您的程序必须显式地执行此初始化,如下:
为组件 sqlvar_struct 结构分配内存,每一列一个 sqlvar_struct 结构。
您可使用诸如 malloc() 或 calloc() 这样的系统内存分配函数,并指定地址为 sqlvar,
如下:
da_ptr->sqlvar = (struct sqlvar_struct *)
calloc(count, sizeof(struct sqlvar_struct));

执行下列任务来描述每一未知的列:
设置 sqlda.sqld 字段,其包含以数据初始化了的 sqlvar_struct 结构的数目。此值为准
备好的语句中未知的列的数目。
初始化每一 sqlvar_struct 结构的字段。
设置 sqltype、
sqllen 和 sqlname 字段
(对于 CHAR 类型数据,
或对于 DATETIME
或 INTERVAL 数据的限定符),来将关于列的信息提供给数据库服务器。

要提供列数据,您的程序还必须为此数据分配空间,并将每一

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 571 -

sqlvar_struct 结构的 sqldata 字段设置为此空间内的恰当位置。
如果您将列
数据发送给数据库服务器,则请务必正确地设置 sqlind 字段。

如果您使用 sqlda 结构来定义输入参数,则您不可使用 DESCRIBE 语句来
初始化 sqlda 结构。您的代码必须显式地设置 sqlda 结构的恰当的字段,来
定义输入参数。
为列数据分配内存
sqlda 结构为 sqlvar_struct 结构的 sqldata 字段中的每一列存储一个指向该数据的
指针。
不像 DESCRIBE...USING SQL DESCRIPTOR 语句那样,
DESCRIBE...INTO 语句不
为此数据分配内存。当 DESCRIBE...INTO 语句为 sqlda 指针分配内存时,它将每一
sqlvar_struct 结构的 sqldata 字段初始化为空。

要发送或接收数据库中的列数据,您的 GBase 8s ESQL/C 程序必须执行下列任务:
为该列数据分配内存。
将与该列相关联的 sqlvar_struct 结构的 sqldata 字段,设置为为该列数据分配的内存
的地址。

要为 sqldata 字段分配内存,
您可使用系统内存分配函数,
比如 malloc() 或 calloc()。
作为对 malloc() 系统内存分配函数的替代,您可程序可为该数据缓冲区声明静态的字符缓
冲区。下图展示从名为 data_buff 的静态字符缓冲区分配列数据的代码片段。

图 6. 从静态的字符缓冲区分配列数据

static char data_buff[1024];
struct sqlda *sql_descp;
struct sqlvar_struct * col_ptr;
short cnt, pos;
int size;


for(col_ptr=sql_descp->sqlvar, cnt=pos=0; cnt < sql_descp->sqld;
cnt++, col_ptr++)
{
pos = (short)rtypalign(pos, col_ptr->sqltype);
col_ptr->sqldata = &data_buf[pos];

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 572 -

size = rtypmsize(col_ptr->sqltype, col_ptr->sqllen);
pos += size;
}

您可在 for 循环内以一系列系统内存分配调用来替代 图 1中的代码片段。
然而,系统内存分配调用可能代价高昂,因此,更加高效的方式,通常是分配
单个内存,然后将指针对准至该内存区域内。

当您分配列数据时,请务必为列数据类型格式化分配了的内存。此数据类型为
GBase 8s ESQL/C 或定义在 sqltypes.h 头文件中的 SQL 数据类型之一。请使
得分配了的内存足够大,以容纳该列中数据的最大大小。

您还必须确保每一列的数据开始于内存中正确的词边界上。在许多硬件平台上,整数
和其他数值数据类型必须开始于词边界上。C 语言内存分配例程分配与包括结构的任何数
据类型恰当一致的内存,但该例程不对该结构的组成部件执行校准。

使用正确的词边界,确保数据类型与机器无关。为了在此任务中辅助您, GBase 8s
ESQL/C 提供下列内存管理函数:
对于指定的数据类型,rtypalign() 函数返回下一个正确的词边界的位置。
此函数接受两个参数:在数据缓冲区中的当前位置,以及整数 GBase 8s ESQL/C 或
您想要为其分配空间的 SQL 数据类型。

rtypmsize() 函数返回内存的字节数,您必须为指定的 GBase 8s ESQL/C 或 SQL 数
据类型分配该内存。
此函数接受两个参数:
整数 GBase 8s ESQL/C 或对于每一列值的 SQL 数据类型
(在
sqltype 中)和长度(在 sqllen 中)。

当您为 DATETIME 或 INTERVAL 数据类型分配内存时,您可采取下列行动,来设
置 dtime_t 和 intrvl_t 结构中的限定符:
请使用在相关联的 sqlda 的 sqllen 字段中的值。
以该值与 datatime.h 头文件定义的宏组成一个不同的限定符。
将数据类型限定符设置为 0,并使得数据库服务器在访存期间设置此限定符。对于
DATETIME 值,
该数据类型限定符为 dtime_t 结构的 dt_qual 字段。
对于 INTERVAL 值,
该数据类型限定符为 intrvl_t 结构的 in_qual 字段。

要获取为 sqldata 字段分配内存的示例,请参阅 demo3.ec 和 unload.ec 演示程序,

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 573 -

以 GBase 8s ESQL/C 提供这些程序。
指定并从 sqlda 结构取得值
当您以动态 SQL 使用 sqlda 结构时,您必须以 C 语言语句将信息移入和移除它。

指定值

要将值指定给 sqlda 和 sqlvar_struct 结构中的字段,请使用常规的 C 语言赋值给
恰当的结构的字段。例如:
da_ptr->sqld = 1;
da_ptr->sqlvar[0].sqldata = compny_data;
da_ptr->sqlvar[0].sqltype = SQLCHAR; /* CHAR data type */
da_ptr->sqlvar[0].sqllen = 21; /* column is CHAR(20) */

设置 sqlda 字段来为 WHERE 子句中的输入参数提供值(指定输入参数值),
或在您使用 DESCRIBE...INTO 语句来填充 sqlda 结构之后来修改字段的内容
(为列数据分配内存)。

取得值

要从 sqlda 字段取得值,您还必须使用来自该结构的字段的常规的 C 语言赋值。例
如:
count = da_ptr->sqld;
/* Allow for the trailing null character in C character arrays */
if (da_ptr->sqlvar[0].sqltype == SQLCHAR)
a_ptr->sqlvar[0].sqllen += 1;
/* Allocate a separate buffer per column */
da_ptr->sqlvar[0].sqldata = malloc(col_ptr->sqllen);

通常,
您取得 sqlda 字段值来检测 SELECT、
INSERT 或 EXECUTE
FUNCTION
语句中列的描述。您还可能需要访问这些列,来将由数据库服务器返回的列值
从 sqlda 结构复制至主变量
(将列值放至 sqlda 结构内)

在后者的情况下,
您可能需要更改 sqllen 来说明正确的缓冲区长度。例如,您必须对 CHAR 数
据类型增加 sqllen。如果您未增加 sqllen,则会截断访存到的数据的最后一
个字符,因为 FETCH 会假设 sqllen 值为该缓冲区的大小,并会将缓冲区中的
最后位置用作零来终止该字符串。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 574 -


主变量的数据类型必须与 sqlda 结构中相关联的字段的类型相兼容。当您
解释 sqltype 字段时,请确保您使用匹配您的环境的数据类型值。对于某些数
据类型,X/Open 值不同于 GBase 8s 值。
指定输入参数值
由于 DESCRIBE...INTO 语句不分析 WHERE 子句,因此,您的程序必须显
式地分配 sqlda 结构和 sqlvar_struct 结构。要描述输入参数,您必须确定
输入参数的数目以及它们的数据类型,并将此信息存储在分配了的 sqlda 结构
中。

当您执行参数化的语句时,您必须包括 USING DESCRIPTOR 子句来指定 sqlda 结
构作为输入参数值的位置,如下:
对于 SELECT 语句的 WHERE 子句的输入参数,请使用 OPEN...USING
DESCRIPTOR 语句。
此语句处理顺序的、
滚动的、
保存或更新游标。
如果您确定该 SELECT
仅返回一行,则可使用 EXECUTE...INTO...USING SQL DESCRIPTOR 语句,而不使用游
标。
对于非 SELECT 语句的 WHERE 子句中的输入参数,诸如 DELETE 或 UPDATE,
请使用 EXECUTE...USING DESCRIPTOR 语句。
对于 INSERT 语句的 VALUES 子句中的输入参数,
请使用 EXECUTE...USING SQL
DESCRIPTOR 语句。如果该 INSERT 与插入游标相关联,则请使用 PUT...USING
DESCRIPTOR 语句。
将列值放至 sqlda 结构内
当您动态地创建 SELECT 语句时,您不可使用 FETCH 的 INTO host_var 子句,因
为您不可在准备好的语句中命名主变量。要将列值访存至 sqlda 结构内,请使用 FETCH
的 USING DESCRIPTOR 子句,
而不用 INTO 子句。
FETCH...USING DESCRIPTOR 语句
将每一列值放至它的 sqlvar_struct 结构的 sqldata 字段内。

使用 FETCH...USING DESCRIPTOR 语句,
假设游标与准备好的语句相关联。
您必须
总是为 SELECT 语句和游标函数(返回多行的 EXECUTE FUNCTION 语句)使用游标。
然而,如果这些语句之一仅返回一行,则您可省略游标,并以 EXECUTE...INTO
DESCRIPTOR 语句将列值检索至 sqlda 结构内。

重要: 如果您执行返回多行的 SELECT 语句或用户定义的函数,且未将该语句与游
标相关联,
则您的程序生成运行时刻错误。
当您将单个 SELECT
(或 EXECUTE FUNCTION)
语句与游标相关联时,GBase 8s ESQL/C 不生成错误。因此,总是将动态 SELECT 或
EXECUTE FUNCTION 语句与游标相关联,
并使用 FETCH...USING DESCRIPTOR 语句来
将列值从此游标检索至 sqlda 结构,是一种好的做法。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 575 -


一旦列值在 sqlda 结构中,
您就可将这些值从 sqldata 移至恰当的主变量。
在运行时
刻,
您必须使用 sqllen 和 sqltype 字段来确定该主变量的数据类型。
您可能需要在 sqltype
字段中的数据类型与保存返回的值的主变量的 GBase 8s ESQL/C 数据类型之间执行数据
类型或长度转换。
释放分配给 sqlda 结构的内存
一旦您以 sqlda 结构结束,就请释放相关联的内存。如果您执行多个 DESCRIBE 语
句,且忽略由这些语句分配的内存,则您的应用程序可能冲击内存限制,且数据库服务器
可能退出。

如果在 Windows(TM) 操作系统上运行您的应用程序,且使用多线程库,则请使用
GBase 8s ESQL/C 函数 SqlFreeMem() 来释放 sqlda 结构所占的内存,如此示例所示:
SqlFreeMem(sqlda_ptr, SQLDA_FREE);

否则,请使用标准 C 库 free() 函数,如此示例所示:
free(sqlda_ptr);

对于同一准备好的语句,
如果您的 GBase 8s ESQL/C 程序执行 DESCRIBE 语句多次,
并为每一 DESCRIBE 分配单独的 sqlda 结构,则它必须显式地释放每一 sqlda 结构。下
图展示一个示例。

图 7. 为同一准备好的语句释放多个 sqlda 结构

EXEC SQL prepare qid from 'select * from customer';
EXEC SQL describe qid into sqldaptr1;
EXEC SQL describe qid into sqldaptr2;
EXEC SQL describe qid into sqldaptr3;

¹
free(sqldaptr1);
free(sqldaptr2);
free(sqldaptr3);

如果你的程序为列数据分配了空间,则您还必须释放分配给 sqldata 字段的内存。

GBase 8s ESQL/C 编程指南
南大通用数据技术股份有限公司
- 576 -

(SQL 管理 API)
随同 admin() 或 task() 函数,使用 onsmsync 参数来将 sysutils 数据库和紧急 boot
文件与存储管理器目录同步。
语法

元素
描述
关键考虑
无选项
将 sysutils 数据库
和紧急 boot 文件与
存储管理器目录同步。

无。
-b
从彼此重新生成紧急
boot 文件
(ixbar.servernum)
和 sysutils 数据
库。
如果 ixbar 文件为空或不存在,则
onsmsync -b 重新创建 ixbar 文件并从
syutils 表填入它。
如果 ixbar 不为空且包含对象数据,
则 onsmsync -b 更新 sysutils 数据
库和 ixbar 文件,以便它们同步。

GBase 8s 管理员参考
南大通用数据技术股份有限公司 - 785 -
元素
描述
关键考虑
如果 ixbar 文件有条目且 sysutils
数据库已重构,但因为它不包含文件而
为空,则 onsmsync -b 选项重新从
ixbar 创建 sysutils 数据。
-b 元素不与其他 onsmsync 选项一起
使用。另外,它不与存储管理器同步。
dbspace
指定一个或多个要终
止的存储空间
如果您输入多于一个存储空间,
则请使用
空格来分隔名称。
-f file_name
指定包含要终止的存
储空间列表的文件的
路径名
使用这个选项来避免键入一个存储空间
的长列表。文件名可为任何有效的 UNIX
™ 或 Windows™ 文件名。
-g
number_of_generations
保留每一 0 级备份的
一定数目的版本
保留备份的最近一版,
且终止所有的较早
版本。
-i interval
终止早于某些时间期
间的所有备份
保留晚于这个间隔的备份。
如果需要从那
个间隔之后的其他备份恢复,
则不终止早
于间隔的备份。使用 interval 的 ANSI
或 GLS 格式:YYYY-MM 或 DD HH:MM:SS
-s
跳过存储管理器已终
止的备份
使用这个选项来跳过与那些从存储管理
器已经终止的对象的同步。如果提供 -s
选项,则会根据其他的参数终止对象。
-O
严格地实施终止策略 如果随同 -t、-g 或 -i 选项一起使用,
则终止所有级别的备份,
即使其中的一些
需要从终止日期之后发生的备份来恢复。
-O 选项不影响逻辑日志终止。请参
阅 ../bar/ids_bar_273.html#ids_bar_
273。
-t date_time
终止特定时间和日期
之前的所有备份
保留晚于这个 datetime 的备份。
如需要
从晚于那个 datetime 的其他备份来恢

GBase 8s 管理员参考
南大通用数据技术股份有限公司 - 786 -
元素
描述
关键考虑
复,
则不终止早于 datetime 的备份。

使用 datetime 的 ANSI 或
GLS_DATETIME 格式。

用法
这个函数调用 onsmsync 实用程序来将 sysutils 数据库和紧急 boot 文件与存储管理器
目录同步。
示例
下列示例调用 onsmsync 实用程序并指定保留的备份数目为 1 且终止所有较早的备份版
本:
EXECUTE FUNCTION task("onsmsync", "-g 1");

RETURN NEXT 及RETURN QUERY
语法
创建函数时需要指定返回值SETOF datatype。
return_next_clause::=
return_query_clause::=
对以上语法的解释如下:
当需要函数返回一个集合时,
使用RETURN
NEXT 或者RETURN
QUERY 向结果
集追加结果,
然后继续执行函数的下一条语句。
随着后续的RETURN
NEXT或RETURN
QUERY 命令的执行,结果集中会有多个结果。函数执行完成后会一起返回所有结果。
RETURN NEXT 可用于标量和复合数据类型。
RETURN QUERY 有一种变体RETURN
QUERY
EXECUTE,
后面还可以增加动态查
询,通过USING 向查询插入参数。
示例
postgres=# CREATE TABLE t1(a int); postgres=# INSERT INTO t1 VALUES(1),(10);
--RETURN NEXT
postgres=# CREATE OR REPLACE FUNCTION fun_for_return_next() RETURNS SETOF
t1 AS $$ DECLARE
r t1%ROWTYPE;

GBase 8c V5 开发者手册
南大通用数据技术股份有限公司
644
BEGIN
FOR r IN select * from t1 LOOP
RETURN NEXT r; END LOOP; RETURN;
END;
$$ LANGUAGE PLPGSQL;
postgres=# call fun_for_return_next(); a
--- 1
10
(2 rows)
-- RETURN QUERY
postgres=# CREATE OR REPLACE FUNCTION fun_for_return_query() RETURNS
SETOF t1 AS $$ DECLARE
r t1%ROWTYPE;
BEGIN
RETURN QUERY select * from t1; END;
$$
language plpgsql;
postgres=# call fun_for_return_query(); a
---
1
10
(2 rows)