lightdb 支持object type

文章目录

  • 概述
  • 语法
    • 类型声明
    • 类型体定义
    • 类型体删除
    • 类型删除
  • 描述
  • 案例演示
  • 结论

概述

在信创移植的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;

描述

  1. OBJECT TYPE类型声明中的函数/存储过程与类型体定义的函数/存储过程数目以及签名需要一致,否则创建类型体定义时会失败。
  2. OBJECT TYPE只有类型声明没有函数/存储过程定义时,函数/存储过程直接使用会发生错误。
  3. OBJECT TYPE定义的函数/存储过程有一个隐式入参self ,类型为自身, 目前不支持再显示为函数/存储过程指定self出入参。 (已支持)
  4. 通过隐式入参self变量可以访问到OBJECT TYPE定义的属性字段。
  5. OBJECT TYPE中的函数不能影响self中的值,但是存储过程可以。
  6. OBJECT TYPE支持类型全参构造器。
  7. OBJECT TYPE中定义的函数/存储过程可以通过类型名.方法名的方式调用,第一参数为隐式入参self,需要传入一个本类型的变量。
  8. OBJECT TYPE中定义的函数/存储过程是在PL/oraSQL下执行的。
  9. OBJECT TYPE在PL/oraSQL声明的变量,可以直接调用该类型定义的方法。

案例演示

环境准备

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做了相应支持,但是也存在一些限制,后续还需要持续优化。

你可能感兴趣的:(lightdb,postgresql,数据库)