Oracle 18c db<>fiddle中插入UDT行时如何动态获取用户名?
问题解决步骤
1. 先修复类型体缺失的核心错误
你遇到的ORA-04067错误本质是仅定义了自定义类型的规范(TYPE),但未实现对应的类型体(TYPE BODY)。自定义类型的构造函数必须在类型体中编写具体逻辑,否则Oracle无法识别调用。
补写类型体的示例(可根据实际需求完善构造函数逻辑):
create or replace TYPE BODY "MY_ST_GEOMETRY" AS -- 第一个构造函数:从WKT字符串和SRID初始化 constructor Function my_st_geometry(geom_str clob,srid number) Return self AS result deterministic IS BEGIN -- 此处添加解析geom_str、赋值属性的业务逻辑,示例仅初始化部分字段 self.srid := srid; RETURN; END; -- 第二个构造函数:从坐标和SRID初始化 constructor Function my_st_geometry(x number, y number, z number, m number, srid integer) Return self AS result deterministic IS BEGIN self.minx := x; self.miny := y; self.minz := z; self.minm := m; self.srid := srid; RETURN; END; END; /
2. 动态获取当前用户的实现方法
Oracle内置函数USER可直接返回当前会话的用户名,结合动态SQL即可实现带动态用户前缀的类型调用:
方式一:用动态SQL直接执行插入
DECLARE v_user VARCHAR2(30) := USER; v_sql VARCHAR2(1000); BEGIN v_sql := 'INSERT INTO polygons (id, shape) VALUES (1, ' || v_user || '.MY_ST_GEOMETRY(''polygon ((52 28,58 28,58 23,52 23,52 28))'', 4326))'; EXECUTE IMMEDIATE v_sql; COMMIT; END; /
方式二:创建包装函数简化调用
如果需要多次调用,可封装一个全局函数:
CREATE OR REPLACE FUNCTION create_my_geometry(geom_str CLOB, srid NUMBER) RETURN MY_ST_GEOMETRY DETERMINISTIC IS v_user VARCHAR2(30) := USER; v_geom MY_ST_GEOMETRY; BEGIN EXECUTE IMMEDIATE 'BEGIN :1 := ' || v_user || '.MY_ST_GEOMETRY(:2, :3); END;' USING OUT v_geom, geom_str, srid; RETURN v_geom; END; /
调用时直接使用该函数:
INSERT INTO polygons (id, shape) VALUES (1, create_my_geometry('polygon ((52 28,58 28,58 23,52 23,52 28))', 4326)); COMMIT;
注意事项
- 在db<>fiddle环境中,类型和类型体的引号规则要保持一致(你定义类型时使用了双引号
"MY_ST_GEOMETRY",类型体也要对应使用双引号)。 - 构造函数的
DETERMINISTIC属性需确保逻辑是确定性的(相同输入返回相同输出),否则可能引发性能问题或错误。
内容的提问来源于stack exchange,提问作者User1974
相关产品推荐
相关产品推荐

