在 Oracle 19c 中获取其主体内的 UDT 类型名称

问题描述 投票:0回答:1

最近我遇到了一个案例,我需要在其主体内获取 UDT 名称。我设法找到以下解决方案:

  not final instantiable member function get_type_name
    return varchar2
  is
    l_type_name varchar2(200);
  begin
    l_type_name := sys.anydata.convertObject(self).GetTypeName();
    l_type_name := replace(l_type_name, sys_context('userenv', 'current_schema') || '.');
    return l_type_name;
  end;

因此它返回没有所有者架构的对象名称。

但是仅使用

anydata
来获取类型名称看起来有点奇怪。也许我在
self
参考文献中遗漏了一些神奇的方法?查看了 Oracle 文档,但到目前为止还没有成功。

如果您知道更多“自然”选择,请分享。

oracle oracle19c
1个回答
0
投票

在 Oracle 数据库中,对象是一个尴尬的事后想法,因此没有太多好的函数来检查它们。

一种选择是使用调用堆栈来查看当前正在执行的程序的名称(也称为类型)。 有两种方法可以做到这一点,我将在下面展示。

我能想到的获取类型名称的唯一其他方法是使用

sys_typeid()
,这需要
execute immediate

CREATE TYPE mytype AS OBJECT (
    type_name VARCHAR2(30),
    CONSTRUCTOR FUNCTION mytype(SELF IN OUT NOCOPY mytype) RETURN SELF AS RESULT
) NOT FINAL;
/

CREATE or replace TYPE BODY mytype AS
    CONSTRUCTOR FUNCTION mytype(SELF IN OUT NOCOPY mytype) RETURN SELF AS RESULT IS
    BEGIN
        -- option 1 - call stack
        SELF.type_name := utl_call_stack.subprogram(1)(1);
        -- option 2 - using $$plsql_unit "conditional compilation flag"
        SELF.type_name := $$plsql_unit;
        -- option 3
        execute immediate 'select type_name from user_types where typeid = sys_typeid(:a)' into SELF.type_name using self;
        -- or your way: 
        SELF.type_name := replace(sys.anydata.convertObject(self).GetTypeName(), sys_context('userenv', 'current_schema') || '.');
        RETURN;
    END;
END;
/

select (new mytype()).type_name from dual;

我认为这些都不是非常“自然”或直观的。所以 ANYDATA 解决方案对我来说似乎很好。

© www.soinside.com 2019 - 2024. All rights reserved.