在信创移植的SQL语句中,有来源于Oracle数据库的SQL语句。
在Oracle中存在getClobVal函数,这个函数是Oracle中sys.XMLType的成员方法。
因此在LightDB23.3版本中需要先实现了TYPE支持定义成员方法。
定义一个OBJECT TYPE分为两部分:类型声明和类型体定义。
CREATE TYPE name as_is OBJECT ( [ object_type_element_list ] )
其中 as_is 是:
AS | IS
其中object_type_element_list 是:
TableFuncElementList [ object_type_func_list ]
其中TableFuncElementList 是:
attribute_name data_type [ COLLATE collation ] [, ... ]
其中object_type_func_list 是 :
{ type_function_spec | type_procedure_spec } [, ... ]
其中type_function_spec 是:
MEMBER FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) RETURN rettype
其中type_procedure_spec 是:
MEMBER PROCEDURE func_name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
示例
CREATE TYPE tp as object (
x int,
y int,
member function d(prompt varchar) return varchar,
member procedure p(prompt varchar)
);
CREATE TYPE BODY name as_is subprog_decl_in_type_list END
其中subprog_decl_in_type 是:
{func_decl_in_type | proc_decl_in_type } [ ... ]
其中func_decl_in_type 是:
MEMBER FUNCTION func_name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) RETURN rettype as_is pl_block
其中proc_decl_in_type 是:
MEMBER PROCEDURE func_name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) as_is pl_block
其中as_is 是:
AS | IS
其中pl_block 是:
[ DECLARE decl_stmts ] BEGIN statement [, ...] END [name];
示例
CREATE TYPE BODY tp
AS
member function d(prompt varchar) return varchar
IS
v varchar;
BEGIN
v := '(' || self.x || ',' || self.y || ')';
raise notice '%', v;
return v;
END;
member procedure p(prompt varchar)
IS
BEGIN
raise notice '%', '(' || self.x || ',' || self.y || ')';
END;
END;
/
DROP TYPE BODY name [ CASCADE | RESTRICT ]
示例
DROP TYPE BODY tp;
DROP TYPE [ IF EXISTS ] name [, ...] [ CASCADE | RESTRICT ]
示例
DROP TYPE tp;
环境准备
create database test_objecttype;
\c test_objecttype
定义类型
lightdb@test_objecttype=# CREATE TYPE tp_for_table as object(
lightdb@test_objecttype(# x int,
lightdb@test_objecttype(# y int,
lightdb@test_objecttype(# member function d(prompt varchar) return varchar,
lightdb@test_objecttype(# member procedure p(prompt varchar)
lightdb@test_objecttype(# );
CREATE TYPE
lightdb@test_objecttype=# CREATE TYPE BODY tp_for_table
lightdb@test_objecttype-# AS
lightdb@test_objecttype-# member function d(prompt varchar) return varchar
lightdb@test_objecttype-# IS
lightdb@test_objecttype$# DECLARE
lightdb@test_objecttype$# v varchar;
lightdb@test_objecttype$# BEGIN
lightdb@test_objecttype$# v := '(' || self.x || ',' || self.y || ')';
lightdb@test_objecttype$# raise notice '%:%', prompt, v;
lightdb@test_objecttype$# return v;
lightdb@test_objecttype$# END;
lightdb@test_objecttype$#
lightdb@test_objecttype$# member procedure p(prompt varchar)
lightdb@test_objecttype$# IS
lightdb@test_objecttype$# BEGIN
lightdb@test_objecttype$# raise notice '%:%', prompt, '(' || self.x || ',' || self.y || ')';
lightdb@test_objecttype$# END;
lightdb@test_objecttype$# END;
lightdb@test_objecttype$# /
CREATE TYPE BODY
创建表
lightdb@test_objecttype=# create table tab_for_object_type (val tp_for_table);
CREATE TABLE
构造器插入数据
lightdb@test_objecttype=# INSERT INTO tab_for_object_type VALUES(tp_for_table(1, 2));
INSERT 0 1
lightdb@test_objecttype=# SELECT * FROM tab_for_object_type ORDER BY val asc;
val
-------
(1,2)
(1 row)
构造器构造变量
lightdb@test_objecttype=# declare
lightdb@test_objecttype$# v tp_for_table := tp_for_table(10, 20);
lightdb@test_objecttype$# begin
lightdb@test_objecttype$# raise notice '%', v;
lightdb@test_objecttype$# end;
lightdb@test_objecttype$# /
NOTICE: (10,20)
DO
类型名调用方法
lightdb@test_objecttype=# select tp_for_table.d(val, 'func') from tab_for_object_type;
NOTICE: func:(1,2)
d
-------
(1,2)
(1 row)
PL/oraSQL调用方法
lightdb@test_objecttype=# declare
lightdb@test_objecttype$# r varchar(100);
lightdb@test_objecttype$# v tp_for_table := tp_for_table(10, 20);
lightdb@test_objecttype$# begin
lightdb@test_objecttype$# r := v.d('func');
lightdb@test_objecttype$# raise notice 'result:%', r;
lightdb@test_objecttype$#
lightdb@test_objecttype$# v.p('proc');
lightdb@test_objecttype$# end;
lightdb@test_objecttype$# /
NOTICE: func:(10,20)
NOTICE: result:(10,20)
NOTICE: proc:(10,20)
DO
查询表中的OBJECT TYPE
lightdb@test_objecttype=# declare
lightdb@test_objecttype$# v tp_for_table;
lightdb@test_objecttype$# r record;
lightdb@test_objecttype$# begin
lightdb@test_objecttype$# select val into r from tab_for_object_type;
lightdb@test_objecttype$# v := r.val;
lightdb@test_objecttype$# raise notice '%', v;
lightdb@test_objecttype$# perform v.d('func');
lightdb@test_objecttype$# v.p('proc');
lightdb@test_objecttype$# end;
lightdb@test_objecttype$# /
NOTICE: (1,2)
NOTICE: func:(1,2)
NOTICE: proc:(1,2)
DO
在LightDB23.3版本中,对OBJECT TYPE做了相应支持,但是也存在一些限制,后续还需要持续优化。