Oracle TYPE_USRDTE类型体编译报错PLS-00539问题求助
解决Oracle自定义对象类型的PLS-00539错误
我来帮你搞定这个PLS-00539的错误,顺便拆解下问题根源:你在TYPE_USRDTE类型体里实现的构造函数,和类型规范(也就是CREATE TYPE那一段)的声明不匹配。Oracle的规则是:对象类型的构造函数,默认值属于实现细节,不能写在类型规范的参数列表里——你现在把default user和default sysdate写在规范里了,Oracle会认为类型体里的构造函数是一个没在规范中声明的新子程序,直接抛出错误。
修正后的完整代码
DROP TABLE TAB_MAIN / DROP TYPE TYPE_SYSCOL / DROP TYPE TYPE_USRDTE / DROP SEQUENCE SEQ_GENERIQUE / CREATE SEQUENCE SEQ_GENERIQUE NOCACHE / -- 修正TYPE_USRDTE的类型规范:去掉参数的默认值,只保留参数声明 CREATE TYPE TYPE_USRDTE AS OBJECT( USR VARCHAR2(30), DTE DATE, CONSTRUCTOR FUNCTION TYPE_USRDTE( pUsr varchar2, pDte date ) RETURN SELF AS RESULT ) / -- 类型体中给构造函数参数加上默认值(实现细节放在这里) CREATE TYPE BODY TYPE_USRDTE IS CONSTRUCTOR FUNCTION TYPE_USRDTE( pUsr varchar2 DEFAULT user, pDte date DEFAULT sysdate ) RETURN SELF AS RESULT IS BEGIN SELF.USR := pUsr; SELF.DTE := pDte; END; END; / CREATE TYPE TYPE_SYSCOL AS OBJECT( IDT NUMBER , CRE TYPE_USRDTE, MDF TYPE_USRDTE, CONSTRUCTOR FUNCTION TYPE_SYSCOL(IDT number default -1) RETURN SELF AS RESULT ) / -- 建议加上OR REPLACE,后续修改类型体更方便 CREATE OR REPLACE TYPE BODY TYPE_SYSCOL IS CONSTRUCTOR FUNCTION TYPE_SYSCOL (IDT number default -1) RETURN SELF AS RESULT IS BEGIN SELF.IDT := SEQ_GENERIQUE.NEXTVAL; SELF.CRE := NEW TYPE_USRDTE(user, sysdate); SELF.MDF := NEW TYPE_USRDTE(user, sysdate); RETURN; end; END; / CREATE TABLE TAB_MAIN ( COLSYS TYPE_SYSCOL, COD VARCHAR2(30) ) / INSERT INTO TAB_MAIN(COD, COLSYS) VALUES('TESTCOL1', TYPE_SYSCOL()) / INSERT INTO TAB_MAIN(COD, COLSYS) VALUES('TESTCOL2', TYPE_SYSCOL()) / INSERT INTO TAB_MAIN(COD, COLSYS) VALUES('TESTCOL3', TYPE_SYSCOL()) / INSERT INTO TAB_MAIN(COD, COLSYS) VALUES('TESTCOL4', TYPE_SYSCOL()) / INSERT INTO TAB_MAIN(COD, COLSYS) VALUES('TESTCOL5', TYPE_SYSCOL()) / COMMIT /
关键修正点说明
- TYPE_USRDTE的类型规范:把参数后的
default user和default sysdate删掉,只保留参数的类型和名称——这部分是对外的接口,不能包含实现层面的默认值。 - TYPE_USRDTE的类型体:在构造函数的参数列表里加上默认值,这是实现细节,Oracle允许在这里定义默认值。
这样修改后,你再编译类型体就不会报错了,同时原来的插入、查询逻辑完全不受影响,依然能得到你预期的结果。
内容的提问来源于stack exchange,提问作者BartmanDilaw
相关产品推荐
相关产品推荐

