VastbaseG100

基于openGauss内核开发的企业级关系型数据库。

Menu

TABLE

功能描述

TABLE函数将一个集合类型的数据转换成表格形式,方便进行查询和分析。支持的入参形式包括数组和setof,其中setof又分为return setof(PG风格)以及pipelined函数(Oracle风格)。

Vastbase实现了TABLE函数的以下增强功能:

  • TABLE函数入参支持变量,并且函数返回结果支持COLUMN_VALUE列。

    COLUMN_VALUE:在 Oracle 中关键字 COLUMN_VALUE 也是数据库为没有列名或属性名的内部嵌套表的标量值生成的名称。在这种情况下,COLUMN_VALUE 不是伪列,而是实际的列名。

  • TABLE函数的入参可以为嵌套表类型。

  • TABLE函数的入参可以被类型转换函数CAST修饰。

    由于无法对数组类型或setof类型进行直接转换,因此本特性适用的场景为参数向其自身类型的转换。即形如table(cast(var as A))的使用场景中,变量var必须是A类型,否则将会报错。

注意事项

TABLE函数的增强功能仅在数据库兼容模式为Oracle时支持(即数据库初始化时指定DBCOMPATIBILITY='A')。

语法格式

table(arg);

参数说明

arg

数据集,可以是数组类型或setof。

示例

示例1: 通过TABLE函数将查询的结果集显示为表的形式。

1、创建测试表并插入数据。

CREATE TABLE testtable(id int);
INSERT INTO testtable VALUES(123),(1234);

2、使用表函数查询结果。

SELECT * FROM table(testtable);

返回结果为:

  id
------
  123
 1234
(2 rows)

3、清理测试表。

DROP TABLE testtable;

示例2: TABLE函数入参使用变量。

1、创建自定义类型。

CREATE TYPE nationalstring IS TABLE OF varchar(2000);

2、创建函数。

CREATE OR REPLACE FUNCTION teststr return nationalstring is
na nationalstring;
lcn integer(5);
begin
na(1) := 'abc100';
na(2) := 'abc200';
na(3) := 'abc300';
select count(*) into lcn from table(na);
dbms_output.put_line('写入行数'||lcn);
return na;
end;
/ 

3、设置serveroutput 为on(允许将dbms_output.put_line的输出信息输出至vsql的命令界面的屏幕上)。

set serveroutput on;

4、调用函数。

SELECT * FROM table(teststr());

返回结果为:

 写入行数3
 column_value
--------------
 abc100
 abc200
 abc300
(3 rows)

5、清理环境。

DROP TYPE nationalstring;
DROP FUNCTION teststr;

示例3: table入参使用嵌套表。

1、创建自定义数据类型。

CREATE OR REPLACE TYPE t_test as object(
id integer,
rq date,
mc varchar2(60)
);

2、使用步骤1定义好的t_test数据类型创建自定义类型。

CREATE OR REPLACE TYPE t_test_table AS TABLE OF t_test;

3、创建函数。

CREATE OR REPLACE FUNCTION f_test_array(n in number default null) return t_test_table
as
v_test t_test_table;
begin
for i in 1 .. nvl(n,100) loop
v_test(i) := (i,sysdate,'mc'||i);
end loop;
return v_test;
end;
/

4、调用函数。

SELECT * FROM table(f_test_array(10));

返回结果为:

 id |         rq          |  mc
----+---------------------+------
  1 | 2022-11-04 16:11:56 | mc1
  2 | 2022-11-04 16:11:56 | mc2
  3 | 2022-11-04 16:11:56 | mc3
  4 | 2022-11-04 16:11:56 | mc4
  5 | 2022-11-04 16:11:56 | mc5
  6 | 2022-11-04 16:11:56 | mc6
  7 | 2022-11-04 16:11:56 | mc7
  8 | 2022-11-04 16:11:56 | mc8
  9 | 2022-11-04 16:11:56 | mc9
 10 | 2022-11-04 16:11:56 | mc10
(10 rows)

5、清理环境。

DROP TYPE t_test CASCADE;
DROP TYPE t_test_table;
DROP FUNCTION f_test_array;

示例4: 在with子句中调用table函数,支持column_value列。

1、创建包和包体。

CREATE OR REPLACE PACKAGE package_test AS
TYPE test_Type_List is table of clob INDEX BY varchar2(20);
function func_Pack_para(tmp1_in nvarchar2,tmp2_in nvarchar2) return test_Type_List;
end package_test;
/

CREATE OR REPLACE PACKAGE BODY package_test IS
function func_Pack_para(tmp1_in nvarchar2, tmp2_in nvarchar2) return test_Type_List IS
re_l test_Type_List := test_Type_List();
i int;
begin
re_l('Aa一') := tmp1_in;
re_l('Bb二') := tmp2_in;
re_l('CC') := '333###ccc';
re_l('Bb二') := '22###ccc@_--';
return re_l;
end;
end package_test;
/

2、设置serveroutput 为on(允许将dbms_output.put_line的输出信息输出至vsql的命令界面的屏幕上)。

set serveroutput on;

3、调用函数使用column_value列。

declare
type c_test is ref cursor;
v_cursor2 c_test;
proc_v package_test.test_Type_List:=package_test.func_Pack_para('testTEST测试ちゅうごく~!@#End','222testTEST测试ちゅうごく~!@#End');
v_row2 varchar(400);
begin
open v_cursor2 for
with temp as (select column_value from table(proc_v))
select * from temp;
loop
fetch v_cursor2 into v_row2;
exit when v_cursor2%notfound;
DBMS_OUTPUT.PUT_LINE ('V:'||v_row2);
end loop;
end;
/

返回结果为:

V:testTEST测试ちゅうごく~!@#End
V:22###ccc@_--
V:333###ccc
ANONYMOUS BLOCK EXECUTE

4、清理环境。

DROP PACKAGE package_test;

示例5: 在存储过程中使用TABLE函数,TABLE函数的入参被CAST修饰。

1、创建存储过程。

create or replace procedure proc_test() as
tb1_1219798 NUMBER;
tb2_1219798 TIMESTAMP;
begin
SELECT * INTO tb1_1219798 FROM table(CAST('123' AS NUMBER));
SELECT * INTO tb2_1219798 FROM table(CAST('2022-01-01 12:34:56' AS TIMESTAMP));
RAISE NOTICE 'result %',tb1_1219798;
RAISE NOTICE 'result %',tb2_1219798;
end;
/

2、调用存储过程。

call proc_test();

调用成功,返回结果如下:

NOTICE:  result 123
NOTICE:  result 2022-01-01 12:34:56
 proc_test
-----------

(1 row)

3、清理测试环境。

DROP PROCEDURE proc_test();