Sorry, I'm a little late, but the other answers are incorrect, at least using Oracle 11gR2, and what you are trying to achieve is really possible.
I just stumbled upon a problem recently, and I see that can finally return the SELF link just like you tried , without compromising or applying workarounds.
The only thing needed is to override the method (explicitly) by setting the (implicit) SELF parameter as SELF IN OUT rectangle .
SELF is the leading parameter, which is silently passed to each object, and for functions it is defined as IN (immutable, this is what seems to make the compiler complain). This is similar to compilation time, but the good part is that when you call a method, you can omit it.
In the example at the end of the message (slightly rewritten from yours), we define
MEMBER FUNCTION incrementWidth(SELF IN OUT rectangle, w NUMBER) RETURN rectangle
and we execute it without a SELF link:
declare r rectangle := rectangle(1,2); begin dbms_output.put_line('width is: ' || r.width); dbms_output.put_line('new width is: ' || r.incrementWidth(3).width); end; /
Please note that there are two warnings to be aware of.
warning 1
Each method call temporarily creates a new copy of the object.
But only temporarily, the new instance is short-lived, only between the beginning and the end of the method. This is due to the use of IN OUT parameters for all functions or procedures and does not apply to object types. If you want to prevent this behavior, you can override the signature of your function using the NOCOPY hint:
MEMBER FUNCTION incrementWidth(SELF IN OUT NOCOPY rectangle, w NUMBER) RETURN rectangle
See ORACLE-BASE - NOCOPY for more details . Please note that this is a hint, but this does not guarantee that you are finally using the same object reference and not just the newly created object, so use it with caution.
warning 2
Given that you raised this question, it is likely that you have an OOP background, and you might get a surprise when trying to call a method without using a return link, such as
r.incrementWidth(10);
The compiler will return an error:
PLS-00221: 'INCREMENTWIDTH' is not a procedure or is undefined
So what is going on here? Well, the so-called "static polymorphism" (i.e. choosing the method overload at compile time) in pl / sql is slightly different from other OOP languages, since it even takes into account the use of the RETURNed type. To solve this problem, add a companion procedure with a signature whose only difference is the absence of a return type:
MEMBER FUNCTION incrementWidth(SELF IN OUT rectangle, w NUMBER) RETURN rectangle, MEMBER PROCEDURE incrementWidth(SELF IN OUT rectangle, w NUMBER)
It is reasonable if you do not want to duplicate the same code in the function and procedure, the procedure will internally delegate the function; and depending on the version of Oracle you are using, you can play with code embedding (see OCP: new PL / SQL functions ) to achieve the same speed as a copy implementation (you hardly notice the real difference). Explicit "inserts" of points in a method by name, however, it also works in this case when the method name is overloaded.
In the example below, you will see that either the function or the procedure is alternatively called depending on the use of the returned / not _returned parameter.
so finally ...
The code you want to write is as follows: I did not use NOCOPY , so as not to contaminate the relevant materials, but it is easy to do)
CREATE OR REPLACE TYPE rectangle AS OBJECT ( length NUMBER, width NUMBER, CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER) RETURN SELF AS RESULT, MEMBER FUNCTION incrementWidth(SELF IN OUT rectangle, w NUMBER) RETURN rectangle, MEMBER PROCEDURE incrementWidth(SELF IN OUT rectangle, w NUMBER) ); / CREATE OR REPLACE TYPE BODY rectangle AS CONSTRUCTOR FUNCTION rectangle(length NUMBER, width NUMBER) RETURN SELF AS RESULT AS BEGIN SELF.length := length; SELF.width := width; RETURN; END; MEMBER FUNCTION incrementWidth(SELF IN OUT rectangle, w NUMBER) RETURN rectangle IS BEGIN dbms_output.put_line('...invoking the function with input ' || w); width := width + w; RETURN SELF; END; MEMBER PROCEDURE incrementWidth(SELF IN OUT rectangle, w NUMBER) IS BEGIN PRAGMA INLINE (incrementWidth, 'YES'); dbms_output.put_line('...invoking the procedure with input ' || w || ', that in turn is...'); self := incrementWidth(w); END; END; /
After doing ...
set serveroutput on select * from v$version where rownum = 1; declare r rectangle := rectangle(1,2); begin dbms_output.put_line('width is: ' || r.width);
You are getting
BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 - 64bit Production width is: 2 ...invoking the function with input 3 new width is: 5 original object has width updated: 5 ...invoking the procedure with input 3, that in turn is... ...invoking the function with input 3 again what is the new width like now?: 8