Oracle Типы объектов: почему изменение атрибута объекта не оказывает влияния после присвоения его родительскому объекту? - PullRequest
0 голосов
/ 29 января 2020

Допустим, у меня есть два Oracle Типа объекта: Сотрудник и Менеджер (определения приведены ниже)

Если я выполню этот код, тогда employee -> manager.name - это "Johnson":

DECLARE
  employee EMPLOYEE_OT;
  manager MANAGER_OT;
BEGIN
  employee := EMPLOYEE_OT(123, 'Robinson');
  manager := MANAGER_OT(321, 'Peeters');

  manager.name := 'Johnson';    -- <=== first rename
  employee.manager := manager;  -- <=== then assign

END;

==> employee.manager.name = "Johnson"

Но если я сначала назначу менеджера сотруднику до изменения имени, тогда employee -> manager.name останется "Peeters":

DECLARE
  employee EMPLOYEE_OT;
  manager MANAGER_OT;
BEGIN
  employee := EMPLOYEE_OT(123, 'Robinson');
  manager := MANAGER_OT(321, 'Peeters');

  employee.manager := manager;  -- <=== first assign
  manager.name := 'Johnson';    -- <=== then rename

END;

==> employee.manager.name = "Peeters"

Как это исправить?

Определения:

Сотрудник:

create or replace TYPE EMPLOYEE_OT FORCE
AS OBJECT (
     id NUMBER
,    name VARCHAR2 (256 CHAR)
,    manager MANAGER_OT

,    CONSTRUCTOR FUNCTION EMPLOYEE_OT (
         p_id NUMBER
       , p_name VARCHAR2
       , p_manager MANAGER_OT
     ) RETURN SELF AS RESULT
);

create or replace TYPE BODY EMPLOYEE_OT AS

  CONSTRUCTOR FUNCTION EMPLOYEE_OT (
            p_id NUMBER
       ,    p_name VARCHAR2
       ,    p_manager MANAGER_OT
      )
    RETURN SELF AS RESULT
  AS
  BEGIN
    SELF.id := p_id;
    SELF.name := p_name;
    SELF.manager := p_manager;
    RETURN;
  END;
end;
/

Менеджер:

create or replace TYPE MANAGER_OT FORCE
AS OBJECT (
     id NUMBER
,    name VARCHAR2 (256 CHAR)

,    CONSTRUCTOR FUNCTION MANAGER_OT (
         p_id NUMBER
       , p_name VARCHAR2
     ) RETURN SELF AS RESULT
);

create or replace TYPE BODY MANAGER_OT AS

  CONSTRUCTOR FUNCTION MANAGER_OT (
            p_id NUMBER
       ,    p_name VARCHAR2
      )
    RETURN SELF AS RESULT
  AS
  BEGIN
    SELF.id := p_id;
    SELF.name := p_name;
    RETURN;
  END;
end;
/
...