1

Is it possible for an Oracle package (PL/SQL) or object function to return a reference to one of it's attributes, so that in the calling scope an assignment made to that attribute updates the attribute in the object instance or package?

Here is a more involved db<>fiddle, but below is a slimmed down db<>fiddle version.

create or replace type obj as object(
  vc varchar2(100)
);

create or replace package pkg as
  o obj;
  
  function f return obj;
end;
/

create or replace package body pkg as
  function f return obj as
  begin
    return o;
  end;
begin
  o := new obj('hello');
end;
/
begin  
  pkg.f().vc := 'planet';  --PLS-00363: expression 'PKG.F().VC' cannot be used as an assignment target
end;
/
create or replace type parent as object(
    o obj
  , member function f( self in out nocopy parent ) return obj
  , constructor function parent return self as result
);

create or replace type body parent as
  member function f( self in out nocopy parent ) return obj as
  begin
    return self.o;
  end;
  
  constructor function parent return self as result as
  begin
    self.o := new obj('hello');
    return;
  end;
end;
/
declare
  p parent := new parent();
begin
  p.f().vc := 'world';  --PLS-00363: expression 'FIDDLE_UEQRJIDDWGWTTMRHYISU.PARENT.F(P).VC' cannot be used as an assignment target
end;
/

Using Oracle 19c Enterprise Edition. Thank you in advance.

Barbaros Özhan
  • 59,113
  • 10
  • 31
  • 55
Alex Bartsmon
  • 471
  • 4
  • 9
  • Related to https://stackoverflow.com/questions/25687106/pl-sql-any-trick-to-avoid-cloning-of-objects ... possibly a duplicate. – MT0 Jan 28 '22 at 00:28
  • You can use `BEGIN pkg.o.vc := 'planet'; END; /` but if you use `DECLARE value obj; BEGIN value := pkg.f(); value.vc = 'planet'; END; /` then `value` will hold a local copy of the object and any changes will not be reflected in the package's object. – MT0 Jan 28 '22 at 00:43
  • Your 'more involved' fiddle shows that you know you can assign the function result to a local variable, and that modifying that doesn't affect the type/package object's value; so you want to know if you can change that behaviour so that local changes *are* reflected, right? I think that's what your first paragraph and longer fiddle are saying, but the short fiddle and code in the question look like they're asking something else - about modifying without assigning (hence MTO's comment). I don't think what (I think) you're asking is possible though. – Alex Poole Jan 28 '22 at 08:52
  • @Alex Poole. Q:"...local changes *are* reflected, right?" A: Yes. The short fiddle and code ```pkg.f().vc := 'planet';``` and ```p.f().vc := 'world';``` are attempts to modify *and* assign without first creating a local ``obj``. These attempt to modify the package/parent's ``o`` object's ``vc`` attribute via the assignment operator ``:=``. Why do you say "...modify **without** assigning"? – Alex Bartsmon Jan 28 '22 at 19:15
  • * ...are attempts to modify and assign without first creating a local obj and not accessing ``o`` directly (as in MTO's comment ```pkg.o.vc := 'planet';``` or ```p.o.vc := 'world';```). – Alex Bartsmon Jan 28 '22 at 19:24
  • @AlexBartsmon - I meant `p.f().vc :=` modifying the returned object without first assigning that to a local `o` variable; rather than referring to the assignment operator you do have - sorry for the confusing terminology *8-) From just the code in the question, it kind of looks like that is what you want to do, which isn't really the case - you want `o` to *be* the package/type object, not a copy of it. I think. – Alex Poole Jan 28 '22 at 20:11

0 Answers0