最近我遇到了一个案例,我需要在其主体内获取 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 数据库中,对象是一个尴尬的事后想法,因此没有太多好的函数来检查它们。
一种选择是使用调用堆栈来查看当前正在执行的程序的名称(也称为类型)。 有两种方法可以做到这一点,我将在下面展示。
我能想到的获取类型名称的唯一其他方法是使用
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 解决方案对我来说似乎很好。