如何在PostgreSQL中创建类似Oracle的带构造函数的TYPE
Oracle带构造函数的对象类型转PostgreSQL的正确方式
你的PostgreSQL转换代码存在几个关键语法错误,这是因为Oracle和PostgreSQL的自定义类型体系差异很大,具体问题和修正方案如下:
核心错误点
- PostgreSQL没有
CREATE TYPE BODY语法,这是Oracle独有的对象类型实现方式 - 不能在
CREATE TYPE的结构定义里声明构造函数,PostgreSQL复合类型仅用于定义数据结构,构造逻辑要通过独立函数实现 NOCOPY是Oracle的优化特性,PostgreSQL不支持,直接移除即可- 函数语法完全错误:
RETURNS SELF AS、DECLARE $$ RESULT IS都是不符合PostgreSQL语法的写法
正确转换代码
第一步:创建复合类型
先定义类型结构,和你不带构造函数时的正确写法一致:
CREATE TYPE "GSMADMIN_INTERNAL".database_dsc_t AS ( version double precision, do_sync_db double precision, do_start_svc double precision, do_mod_local_svc double precision, want_ons_config double precision, db_number double precision, cloud_name varchar(128), dbpool_name varchar(128), region_name varchar(128), shdgrp_name varchar(128), shdgrp_id double precision, num_inst double precision, cpu_thld double precision, disk_thld double precision, do_force double precision, chunks double precision, service_list service_dsc_list_t, region_list region_list_t, gsm_list gsm_list_t, ons_port varchar(256), scan_name varchar(256), hostname varchar(256), db_type char, sharding_type double precision, deploy_as double precision, status double precision, shardspace_name varchar(128), shardspace_id double precision, repl_type double precision, MINNUM double precision, MAXNUM double precision, DBLPWD varchar(64), DBLEP varchar(256), GWM_INTDBNUM double precision );
第二步:创建自定义构造函数
PostgreSQL通过普通函数模拟构造函数逻辑,这里提供两种实现方式:
方式1:直接返回新实例(更简洁)
CREATE OR REPLACE FUNCTION "GSMADMIN_INTERNAL".database_dsc_t(dbnum double precision) RETURNS "GSMADMIN_INTERNAL".database_dsc_t AS $$ DECLARE result "GSMADMIN_INTERNAL".database_dsc_t; BEGIN -- 初始化指定字段,其余字段保持默认值 result.db_number := dbnum; RETURN result; END; $$ LANGUAGE plpgsql;
方式2:贴近Oracle SELF写法(用INOUT参数)
CREATE OR REPLACE FUNCTION "GSMADMIN_INTERNAL".database_dsc_t(INOUT self "GSMADMIN_INTERNAL".database_dsc_t, dbnum double precision) RETURNS "GSMADMIN_INTERNAL".database_dsc_t AS $$ BEGIN self.db_number := dbnum; END; $$ LANGUAGE plpgsql;
使用构造函数
调用方式示例:
-- 方式1调用示例 SELECT "GSMADMIN_INTERNAL".database_dsc_t(123); -- 方式2调用示例 SELECT * FROM "GSMADMIN_INTERNAL".database_dsc_t(NULL, 123);
内容的提问来源于stack exchange,提问作者Ranjan
相关产品推荐
相关产品推荐

