PL/SQL ORA-30625:不允许对NULL SELF参数进行方法调度



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

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

代码如下:

创建或替换类型PEDIDO_TP作为对象(edido号,DATA_PAGAMENTO日期,取消次数(1),PENDURADO数(1),会员程序cancelapedio(编号n));
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>   

在使用构造函数调用创建对象之前,对象为null。从Oracle文档,

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

所以,你需要这样做:

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

文档链接

**--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 ...

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

声明x PEDIDO_TP:=PEDIDO_TPP.CONSTRUCT--对对象的引用和对构造函数的调用。

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

确保该端口可用于特定域

select acl , host , lower_port , upper_port from DBA_NETWORK_ACLS;

并确保用户有足够的权限

select acl , principal , privilege , is_grant from DBA_NETWORK_ACL_PRIVILEGES;

ACL教程在这里

最新更新