【问题标题】:PL/SQL ORA-30625: method dispatch on NULL SELF argument is disallowedPL/SQL ORA-30625: 不允许对 NULL SELF 参数进行方法调度
【发布时间】:2018-02-18 17:28:42
【问题描述】:

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

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

代码如下:

 创建或替换类型 PEDIDO_TP 作为对象(
        ID_PEDIDO 号码,
        DATA_PAGAMENTO 日期,
        取消号码(1),
        彭杜拉多号码(1),
        成员程序 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>   

【问题讨论】:

标签: oracle plsql


【解决方案1】:

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

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

所以,你需要这样做:

declare
x PEDIDO_TP;   --reference to the object

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

链接到documentation

【讨论】:

    【解决方案2】:
    **--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 ...
    

    【讨论】:

      【解决方案3】:

      你需要为这个对象调用构造函数,你可以在声明变量时这样做。例如:

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

      【讨论】:

        【解决方案4】:

        它与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教程是HERE

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-09-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多