PLS-00539: 子程序在对象类型主体中声明,必须在对象类型规范中定义

PLS-00539: subprogram is declared in an object type body and must be defined in the object type specification

我正在尝试从基础 class base_t 创建子 class item_t,但它给我错误:

PLS-00539: subprogram 'ITEM_T' is declared in an object type body and must be defined in the object type specification PLS-00538: subprogram or cursor 'ITEM_T' is declared in an object type specification and must be defined in the object type body

不知道哪里出了问题。能帮忙吗

    -- Open log file.
SPOOL example.txt

DROP TYPE item_t FORCE;
DROP TYPE base_t FORCE;


CREATE OR REPLACE TYPE base_t IS OBJECT
(oname VARCHAR2(30)
, name VARCHAR2(30)
, CONSTRUCTOR FUNCTION base_t RETURN SELF AS RESULT
, CONSTRUCTOR FUNCTION base_t (oname VARCHAR2, name VARCHAR2) RETURN SELF AS RESULT
, MEMBER FUNCTION get_name RETURN VARCHAR2
, MEMBER FUNCTION get_oname RETURN VARCHAR2
, MEMBER PROCEDURE set_oname (oname VARCHAR2)
, MEMBER FUNCTION to_string RETURN VARCHAR2
) INSTANTIABLE NOT FINAL;
/


CREATE OR REPLACE TYPE BODY base_t IS
   CONSTRUCTOR FUNCTION base_t RETURN SELF AS RESULT IS
   BEGIN
       self.oname := 'BASE_T';
       RETURN;
   END base_t;
   
   CONSTRUCTOR FUNCTION base_t (oname VARCHAR2, name VARCHAR2) RETURN SELF AS RESULT IS
   BEGIN 
       self.oname := oname;
       self.name := name;
       RETURN;
   END base_t;
   
   MEMBER FUNCTION get_name RETURN VARCHAR2 IS
   BEGIN 
       RETURN NVL(self.name, NULL);
   END get_name;
   
   MEMBER FUNCTION get_oname RETURN VARCHAR2 IS
   BEGIN 
       RETURN self.oname;
   END get_oname;
   
      
   MEMBER PROCEDURE set_oname (oname VARCHAR2) IS
   BEGIN 
       self.oname := oname;
   END set_oname;
   
   MEMBER FUNCTION to_string RETURN VARCHAR2 IS
   BEGIN 
       return '['||self.oname||']';
   END to_string;
   
END;
/


SET PAGESIZE 999
SET SERVEROUTPUT ON


DROP TABLE logger;
/
DROP SEQUENCE logger_s;
/

CREATE SEQUENCE logger_s;

CREATE TABLE logger
(logger_id NUMBER
, log_text base_t);
/



DECLARE
  /* Declare a variable of the UDT type. */
  lv_base  BASE_T;
BEGIN
  /* Assign an instance of the variable. */
  lv_base := base_t(
      oname => 'BASE_T'
    , name => 'NEW' );

    /* Insert instance of the base_t object type into table. */
    INSERT INTO logger
    VALUES (logger_s.NEXTVAL, lv_base);

    /* Commit the record. */
    COMMIT;
END;
/

COLUMN oname     FORMAT A20
COLUMN get_name  FORMAT A20
COLUMN to_string FORMAT A20
SELECT t.logger_id
,      t.log.oname AS oname
,      NVL(t.log.get_name(),'Unset') AS get_name
,      t.log.to_string() AS to_string
FROM  (SELECT l.logger_id
       ,      TREAT(l.log_text AS base_t) AS log
       FROM   logger l) t
WHERE  t.log.oname = 'BASE_T';


CREATE OR REPLACE 
   TYPE item_t UNDER base_t 
    ( item_id NUMBER
    , item_barcode VARCHAR2(20)
    , item_type NUMBER
    , item_title VARCHAR2(60)
    , item_subtitle VARCHAR2(60)
    , item_rating VARCHAR2(8)
    , item_rating_agency VARCHAR2(4)
    , item_release_date DATE
    , created_by NUMBER
    , creation_date DATE
    , last_update_by NUMBER
    , last_update_date DATE
    , CONSTRUCTOR FUNCTION item_t 
    ( oname VARCHAR2
    , name VARCHAR2
    , item_id NUMBER
    , item_barcode VARCHAR2
    , item_type NUMBER
    , item_title VARCHAR2
    , item_subtitle VARCHAR2
    , item_rating VARCHAR2
    , itmer_rating_agency VARCHAR2
    , item_realease_date DATE
    , created_by NUMBER
    , creation_date DATE
    , last_update_by NUMBER
    , last_update_date DATE) RETURN SELF AS RESULT
    , OVERRIDING MEMBER FUNCTION get_name RETURN VARCHAR2
    , OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2)
    INSTANTIABLE NOT FINAL;
/

CREATE OR REPLACE 
  TYPE BODY item_t IS
    CONSTRUCTOR FUNCTION item_t 
    ( oname VARCHAR2
    , name VARCHAR2
    , item_id NUMBER
    , item_barcode VARCHAR2
    , item_type NUMBER
    , item_title VARCHAR2
    , item_subtitle VARCHAR2
    , item_rating VARCHAR2
    , item_rating_agency VARCHAR2
    , item_release_date DATE
    , created_by NUMBER
    , creation_date DATE
    , last_update_by NUMBER
    , last_update_date DATE)
    RETURN SELF AS RESULT IS
BEGIN
    self.oname := oname;
    self.name := name;
    self.item_id := item_id;
    self.item_barcode := item_barcode;
    self.item_type := item_type;
    self.item_title := item_title;
    self.item_subtitle := item_subtitle;
    self.item_rating := item_rating;
    self.item_rating_agency := item_rating_agency;
    self.item_release_date := item_release_date;
    self.created_by := created_by;
    self.creation_date := creation_date;
    self.last_update_by := last_update_by;
    self.last_update_date := last_update_date;
    RETURN;
END item_t;

OVERRIDING MEMBER FUNCTION get_name RETURN VARCHAR2 IS
BEGIN 
    RETURN NVL(self.name, NULL);
END get_name;

OVERRIDING MEMBER FUNCTION to_string RETURN VARCHAR2 IS
 BEGIN 
       return  (self AS base_t).to_string()||'['||self.oname||'].[' || self.name || ']';
   END to_string;

END;
/

SPOOL OFF

type_t

规范中的参数名称有拼写错误
, itmer_rating_agency VARCHAR2 --> item_rating_agency 
, item_realease_date DATE      --> item_release_date 

并且由于这些拼写错误,oracle 认为构造函数不同并出错