我有以下plsql对象:
CREATE OR REPLACE TYPE TestType AS OBJECT
(
firstname VARCHAR2(30),
lastname VARCHAR2(30),
MEMBER PROCEDURE dosomething,
MEMBER function downgrade return number,
CONSTRUCTOR FUNCTION TestType(fname VARCHAR2, lname VARCHAR2) RETURN SELF AS RESULT
)
/
CREATE OR REPLACE TYPE BODY TestType AS
CONSTRUCTOR FUNCTION TestType(fname VARCHAR2, lname VARCHAR2)
RETURN SELF AS RESULT
IS
BEGIN
SELF.firstname := fname;
SELF.lastname := lname;
RETURN;
END;
MEMBER function downgrade return number IS
BEGIN
self.dosomething; /* Compilation Error Here */
return 1;
END;
MEMBER PROCEDURE dosomething IS
BEGIN
null;
END;
END;
/
这是一个复杂对象的例子,基本上从一个成员函数开始,我需要调用一个成员过程,当这样做的时候,我得到了编译错误:PLS-00363:表达式不能用作赋值目标
我不明白为什么会引发此错误。
有人知道我哪里做错了吗?
多谢。干杯,
2条答案
按热度按时间sq1bmfud1#
尽管文件上说:
成员方法有一个名为SELF的内置参数,表示当前调用该方法的对象示例。
SELF可以显式声明,但这不是必须的。...
它后来还说:
SELF始终是传递给方法的第一个参数。
你得到这个错误是因为你的过程调用
隐式地将
self
作为IN OUT
传递给过程,但是它被隐式地作为IN
传递给函数,这意味着它没有处于正确的模式来调用过程--模式意味着过程可以修改self
,而函数说它不会。您可以通过更改函数中的模式来避免此错误,方法是在以下两种类型中显式声明
self
参数:和类型体:
fiddle
如果您的真实的过程不会修改
self
(可能不太可能),那么您可以声明它是self IN
。人们常说函数应该只返回值,而不应该有副作用,所以可以说这是更正确的--调用你的成员函数的人可能不期望它改变任何东西。
所以如果
dosomething
* 正在改变数据,那么downgrade
也应该是一个过程,用一个OUT
参数代替返回值,这样你就不需要声明self
,因为默认情况下两者都是IN OUT
。7vux5j2d2#
以下代码编译成功:
但是你应该仔细测试一下,它是否像预期的那样工作。
否则,您可以将过程更改为函数并忽略返回值:
另一种方法是创建
STATIC PROCEDURE
过程而不是MEMBER PROCEDURE