oracle PL/SQL ORA-30625:不允许对 NULL SELF 参数进行方法分派

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/20620562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 05:24:54  来源:igfitidea点击:

PL/SQL ORA-30625: method dispatch on NULL SELF argument is disallowed

oracleplsql

提问by user3108805

Oracle keeps giving me this error: ORA-30625: method dispatch on NULL SELF argument is disallowed.

Oracle 一直给我这个错误:ORA-30625:不允许对 NULL SELF 参数进行方法调度。

ORA-30625: method dispatch on NULL SELF argument is disallowed

ORA-30625: 不允许对 NULL SELF 参数进行方法分派

The code follows:

代码如下:

  CREATE OR REPLACE TYPE PEDIDO_TP AS OBJECT(
        ID_PEDIDO NUMBER,
        DATA_PAGAMENTO DATE,
        CANCELADO NUMBER(1),
        PENDURADO NUMBER(1),
        member procedure cancelapedido(n in number)
        );     

create or replace type body PEDIDO_TP as member procedure cancelapedido(n in number) is begin DELETE FROM PEDIDO p WHERE p.ID_PEDIDO = n; end; end; CREATE TABLE PEDIDO OF PEDIDO_TP( ID_PEDIDO PRIMARY KEY ); insert into PEDIDO values (PEDIDO_TP(1,'12/12/12',0,0)); declare x PEDIDO_TP; begin x.cancelapedido('1'); end;<code>

回答by OldProgrammer

Your object is null until you create it with a constructor call. From the Oracle Docs,

在您使用构造函数调用创建它之前,您的对象为空。从 Oracle 文档中,

User-defined types, just like collections, are atomically null, until you initialize the object by calling the constructor for its object type

用户定义的类型,就像集合一样,在原子上都是空的,直到您通过为其对象类型调用构造函数来初始化对象

So, you need to do this:

所以,你需要这样做:

declare
x PEDIDO_TP;   --reference to the object

begin
  x := PEDIDO_TP(,,, all your parameters,,,);  --assign created object to the reference.
end;

Link to documentation

文档链接

回答by Pablo Riboldi

You need to call the constructor for this object, and you can do this when you declare the variable. For example:

您需要调用此对象的构造函数,并且您可以在声明变量时执行此操作。例如:

declare x PEDIDO_TP := PEDIDO_TP.CONSTRUCT; --reference to the object and call to constructor.

声明 x PEDIDO_TP := PEDIDO_TP.CONSTRUCT; --引用对象并调用构造函数。

回答by Naveen

**--ORA-30625 (A member method of a type is being invoked with a NULL SELF argument.)**

The issue is simulated with the below cases 

Three Cases:-

**1- Invoking a method without initializing the object 
2- Data is not there in the Payload
3- Data is null in the payload**

--Try to execute the below Scripts 

--CREATE TYPE & TYPE BODY

CREATE OR REPLACE TYPE TEST_TYPE AS OBJECT(
        ID  NUMBER,
        DIGIT NUMBER(1),
        member FUNCTION FACT_CAL(n in number) RETURN NUMBER );

create or replace type body TEST_TYPE as
  member FUNCTION FACT_CAL(n in number) RETURN NUMBER is
  begin
    RETURN SELF.ID * SELF.DIGIT * n;
  end;
END;

**--1- Invoking a method without initializing the object** 

--Issue arises here
DECLARE
   r1 TEST_TYPE;
BEGIN
-- R1 := TEST_TYPE(1,2);
   DBMS_OUTPUT.put_line(R1.FACT_CAL(2));
END;

-----NOW EXECUTE BELOW(issue is resolved here)------

**Solution:-**

DECLARE
   r1 TEST_TYPE;
BEGIN
  R1 := TEST_TYPE(1,2);
   DBMS_OUTPUT.put_line(R1.FACT_CAL(2));
END;

**--2- Data is not there in the Payload**

-----EXECUTE BELOW(Issue arises here)------

DECLARE
   r1 TEST_TYPE;
   r2 sys.anydata;
   r3 number;
BEGIN
-- R1 := TEST_TYPE(null,null);
r3:=r2.getObject(r1);
   DBMS_OUTPUT.put_line(DBMS_TYPES.SUCCESS);
END;

---Now Execute below(--issue is resolved here)----

**Solution :-** 

DECLARE
   r1 TEST_TYPE;
   r2 sys.anydata;
   r3 number;
BEGIN
-- R1 := TEST_TYPE(null,null);
r2:= sys.anydata.ConvertObject(r1);
r3:=r2.getObject(r1);
   DBMS_OUTPUT.put_line(DBMS_TYPES.SUCCESS);
END;

**-- 3- Data is null in the payload**

CREATE OR REPLACE TYPE TEST_TYPE1 AS OBJECT(
        ID  NUMBER,
        DIGIT NUMBER(1) );

create table anydata 
(id number,
data sys.anydata);

  insert into anydata values (1, null);

CREATE OR REPLACE FUNCTION GET_OBJ_TYPE(IN_ANYDATA SYS.ANYDATA)
   RETURN TEST_TYPE1 IS

   V_ANYDATA SYS.ANYDATA := IN_ANYDATA;
   V_BE_DATA TEST_TYPE1 ;
   V_RETURN  PLS_INTEGER;
BEGIN
 V_RETURN := SYS.ANYDATA.GETOBJECT(SELF => V_ANYDATA, OBJ => V_BE_DATA);
 RETURN V_BE_DATA;
END GET_OBJ_TYPE;

--EXECUTE THE QUERY(Issue arises here)

select GET_OBJ_TYPE(data) from anydata;

--NOTE :- PROBLEM IS WHEN THE ANYDATA VALUE IS NULL THIS DATA CANT CONVERT THE PAYLOAD TO SPECIFIC OBJECT TYPE .

-**-SOLUTION** :-

(CONVERT THE 'NULL' ENTRY TO SYS.ANYDATA TYPE) --issue is resolved here


CREATE OR REPLACE FUNCTION GET_OBJ_TYPE(IN_ANYDATA SYS.ANYDATA)
   RETURN TEST_TYPE1 IS

   V_ANYDATA SYS.ANYDATA := IN_ANYDATA;
   V_BE_DATA TEST_TYPE1 ;
   V_RETURN  PLS_INTEGER;
BEGIN
   V_ANYDATA:= sys.anydata.ConvertObject(V_BE_DATA);--- ADD THIS LINE WHICH CONVERTS 'NULL' TO THE SYS.ANYDATA TYPE
   V_RETURN := SYS.ANYDATA.GETOBJECT(SELF => V_ANYDATA, OBJ => V_BE_DATA);

   RETURN V_BE_DATA;
END GET_OBJ_TYPE;

 --NOW EXECUTE THE QUERY`enter code here`
select GET_OBJ_TYPE(data) from anydata;


HOPE THIS IS HELPFUL ...

回答by Bassel Kh

It is related to oracle ACL (Most probably), at least we could fix this issue by resolving the ACL issue.

它与oracle ACL有关(很可能),至少我们可以通过解决ACL问题来解决这个问题。

Make sure that the port is available for that specific domain

确保该端口可用于该特定域

select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;

And make sure that the user has sufficient privilege

并确保用户有足够的权限

select acl , principal , privilege , is_grant from DBA_NETWORK_ACL_PRIVILEGES;

ACL tutorial is HERE

ACL 教程在这里