Я пытаюсь создать таблицу с использованием Oracle TYPES, которая использует TYPES, но получить это предупреждение компиляции при компиляции тела типа "TYPE_USRDTE".

Warning: Type body created with compilation errors

Ошибки компиляции:

Compilation errors for TYPE BODY STRACC.TYPE_USRDTE
#13#10Error: PLS-00539: subprogram 'TYPE_USRDTE' is declared in an object type body and must be defined in the object type specification
Line: 2
Text: CONSTRUCTOR FUNCTION TYPE_USRDTE( pUsr varchar2 default user, pDte date default sysdate ) RETURN SELF AS RESULT IS

Вот общий код:

DROP TABLE TAB_MAIN
/
DROP TYPE TYPE_SYSCOL
/
DROP TYPE TYPE_USRDTE
/
DROP SEQUENCE SEQ_GENERIQUE 
/
CREATE SEQUENCE SEQ_GENERIQUE NOCACHE
/

CREATE TYPE TYPE_USRDTE AS OBJECT(
USR VARCHAR2(30),
DTE DATE,
CONSTRUCTOR FUNCTION TYPE_USRDTE( pUsr varchar2 default user, pDte date default sysdate ) 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
)
/

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
/

Когда я выбираю из TAB_MAIN, я получаю строки, которые я ожидал. Кто-нибудь может помочь мне понять и исправить эту проблему?

0
BartmanDilaw 19 Авг 2019 в 11:18

2 ответа

Лучший ответ

Как и отсутствующий RETURN, ваш заказной конструктор имеет те же аргументы, что и конструктор по умолчанию, что приводит к вашей ошибке "PLS-00307: слишком много объявлений 'TYPE_USRDTE' соответствуют этому вызову". Когда вы звоните:

SELF.CRE := NEW TYPE_USRDTE(user, sysdate);

Компилятор не может сказать, какой из двух очень похожих конструкторов вы имеете в виду. Вы должны дать понять, что вы хотите; все они будут вызывать ваш конструктор на заказ:

SELF.CRE := NEW TYPE_USRDTE(pUsr => user, pDte => sysdate);
SELF.CRE := NEW TYPE_USRDTE(pusr => user);
SELF.CRE := NEW TYPE_USRDTE(pDte => sysdate);
SELF.CRE := NEW TYPE_USRDTE(user);
SELF.CRE := NEW TYPE_USRDTE(sysdate);

Первый из них эквивалентен вашему исходному вызову, но содержит имена аргументов, поэтому его можно сопоставить с конкретными конструкторами. Второй и третий делают то же самое, но только передают один из аргументов, позволяя другому по умолчанию. Третий и четвертый делают то же самое, но, поскольку только конструктор на заказ имеет значения по умолчанию, вам не нужно имя аргумента; все же яснее, если вы включите его. И если у вас есть более одного аргумента с одним и тем же типом данных или есть некоторая двусмысленность в отношении того, как они предоставляются, вам все равно нужны имена.

Чтобы вызвать конструктор по умолчанию, вместо этого вы должны использовать имена атрибутов:

SELF.CRE := NEW TYPE_USRDTE(usr => user, dte => sysdate);

И оба аргумента всегда нужны.

1
Alex Poole 19 Авг 2019 в 10:02

Это может или не может быть реальной проблемой, но одна очевидная проблема с вашим телом типа: отсутствует RETURN

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;
       RETURN; -- this is missing in your code
    END;
END;
/

Ура !!

1
Tejash 19 Авг 2019 в 08:48