想通过oracle 提供的扩展优化器功能定义类型函数的cpucost和iocost,但在执行的过程中出现异常:ORA-6550 received when calling TEST.DBPERIOD.ODCIStatsFunctionCost -- method ignored.
此问题该怎么解决呢?谢谢
代码如下:CREATE OR REPLACE TYPE T_Instant AS OBJECT(
time_point DATE,MAP MEMBER FUNCTION compare RETURN DATE
);CREATE OR REPLACE TYPE BODY T_Instant
ASMAP MEMBER FUNCTION compare RETURN DATE
IS
BEGIN
RETURN time_point;
END compare;end;CREATE OR REPLACE TYPE T_Period AS OBJECT( 
--Period type defination:perid=(instant, instant)
from_t T_Instant,
to_t T_Instant,
CONSTRUCTOR FUNCTION T_period(f_t date, t_t date)
RETURN SELF AS RESULT,
MEMBER FUNCTION M_Before(p T_Period) RETURN VARCHAR2);CREATE OR REPLACE TYPE BODY T_Period ISCONSTRUCTOR FUNCTION T_period(f_t date, t_t date)
RETURN SELF AS RESULT ISBEGIN 
IF(f_t<=t_t)
THEN 
SELF.from_t := T_Instant(f_t);
SELF.to_t := T_Instant(t_t);
RETURN ;
ELSE RAISE_APPLICATION_ERROR(-20000,'Time period is invalid!');END IF;
END;
MEMBER FUNCTION M_Before(p T_Period) RETURN VARCHAR2 IS
BEGIN
IF to_t < p.from_t 
THEN RETURN 'TRUE';
ELSE RETURN 'FALSE';
END IF;
END M_Before;end;
create table p(id number,t t_period);begin 
for i in 1000..2000 loop
insert into p values(i,t_period(t_instant(sysdate+i),t_instant(sysdate+i+1)));
if i mod 200 = 0 then
commit;
end if;
end loop;
end;create or replace type dbperiod as object
(
num number,
STATIC FUNCTION ODCIGetInterfaces(ifclist OUT sys.ODCIObjectList)
RETURN NUMBER,
STATIC FUNCTION ODCIStatsSelectivity(pred sys.ODCIPredInfo,
sel OUT NUMBER, args sys.ODCIArgDescList, strt varchar2, stop varchar2,
p t_period, env sys.ODCIEnv)
RETURN NUMBER,STATIC FUNCTION ODCIStatsFunctionCost(func sys.ODCIFuncInfo,
cost OUT sys.ODCICost, args sys.ODCIArgDescList,
p t_period, env sys.ODCIEnv) RETURN NUMBER
-- PRAGMA restrict_references(ODCIStatsFunctionCost, WNDS, WNPS)
);create or replace type body dbperiod is STATIC FUNCTION ODCIGetInterfaces(ifclist OUT sys.ODCIObjectList)
RETURN NUMBER IS
BEGIN
ifclist := sys.ODCIObjectList(sys.ODCIObject('SYS','ODCISTATS2'));
RETURN ODCIConst.Success; 
END ODCIGetInterfaces;STATIC FUNCTION ODCIStatsSelectivity(pred sys.ODCIPredInfo,
sel OUT NUMBER, args sys.ODCIArgDescList, strt varchar2, stop varchar2,
p t_period, env sys.ODCIEnv)
RETURN NUMBER IS 
begin
sel := 20; --just test
dbms_output.put_line('sel = 20');
RETURN ODCIConst.Success;
END ODCIStatsSelectivity;
STATIC FUNCTION ODCIStatsFunctionCost(func sys.ODCIFuncInfo,
cost OUT sys.ODCICost, args sys.ODCIArgDescList,
p t_period ,env sys.ODCIEnv) RETURN NUMBER IS
fname VARCHAR2(30);
BEGIN
cost := sys.ODCICost(NULL, NULL, NULL, NULL);
-- Get function name
IF bitand(func.Flags, ODCIConst.ObjectFunc) > 0 THEN
fname := upper(func.ObjectName);ELSE
fname := upper(func.MethodName);
END IF;IF fname LIKE upper('%m_before%') THEN
dbms_output.put_line('test ok!');
cost.CPUCost := 200;
cost.IOCost := 10;
RETURN ODCIConst.Success;
else RETURN ODCIConst.Error;
end if;
END ODCIStatsFunctionCost; 
END; associate statistics with types t_period using dbperiod;
select id,a.t from p a where a.t.M_Before(t_period( date'2010-5-20',date'2010-5-21')) = 'TRUE';通过autotrace 跟踪到的执行信息如下:
Calling user-defined function cost function...
    predicate: "TEST"."T_PERIOD"."M_BEFORE"("A"."T","TEST"."T_PERIOD"(TO_DATE('2010-05-20 00:00:00', 'yyyy-mm-dd hh24:mi:ss'),TO_DATE('2010-05-21 00:00:00', 'yyyy-mm-dd hh24:mi:ss')))
  declare 
     cost sys.ODCICost := sys.ODCICost(NULL, NULL, NULL, NULL); 
     obj1 "TEST"."T_PERIOD" := "TEST"."T_PERIOD"(NULL, NULL);
   
    begin 
      :1 := "TEST"."DBPERIOD".ODCIStatsFunctionCost(
                     sys.ODCIFuncInfo('TEST', 
                            'T_PERIOD', 
                            'M_BEFORE', 
                            4), 
                     cost, 
                     sys.ODCIARGDESCLIST(sys.ODCIARGDESC(1, NULL, NULL, NULL, NULL, NULL, NULL)) 
                     , obj1, 
                     sys.ODCIENV(:5,:6,:7,:8)); 
      if cost.CPUCost IS NULL then 
        :2 := -1.0; 
      else 
        :2 := cost.CPUCost; 
      end if; 
      if cost.IOCost IS NULL then 
        :3 := -1.0; 
      else 
        :3 := cost.IOCost; 
      end if; 
      if cost.NetworkCost IS NULL then 
        :4 := -1.0; 
      else 
        :4 := cost.NetworkCost; 
      end if; 
      exception 
        when others then 
          raise; 
    end;
ODCIEnv Bind :5 Value 0
ODCIEnv Bind :6 Value 0
ODCIEnv Bind :7 Value 0
ODCIEnv Bind :8 Value 12
  ORA-6550 received when calling TEST.DBPERIOD.ODCIStatsFunctionCost -- method ignored
  Calling user-defined selectivity function...
    predicate: "TEST"."T_PERIOD"."M_BEFORE"("A"."T","TEST"."T_PERIOD"(TO_DATE('2010-05-20 00:00:00', 'yyyy-mm-dd hh24:mi:ss'),TO_DATE('2010-05-21 00:00:00', 'yyyy-mm-dd hh24:mi:ss')))='TRUE'
  declare 
     sel number; 
     obj1 "TEST"."T_PERIOD" := "TEST"."T_PERIOD"(NULL, NULL);
   
    begin 
      :1 := "TEST"."DBPERIOD".ODCIStatsSelectivity(
                     sys.ODCIPREDINFO('TEST', 
                            'T_PERIOD', 
                            'M_BEFORE', 
                            77), 
                     sel, 
                     sys.ODCIARGDESCLIST(sys.ODCIARGDESC(3, NULL, NULL, NULL, NULL, NULL, NULL), sys.ODCIARGDESC(3, NULL, NULL, NULL, NULL, NULL, NULL), sys.ODCIARGDESC(1, NULL, NULL, NULL, NULL, NULL, NULL)), 
                     :3, 
                     :4 
                     , obj1, 
                     sys.ODCIENV(:5,:6,:7,:8)); 
      if sel IS NULL then 
        :2 := -1.0; 
      else 
        :2 := sel; 
      end if; 
      exception 
        when others then 
          raise; 
    end;
Bind :3 Value 'TRUE'
Bind :4 Value 'TRUE'
ODCIEnv Bind :5 Value 0
ODCIEnv Bind :6 Value 0
ODCIEnv Bind :7 Value 0
ODCIEnv Bind :8 Value 12
  ORA-6550 received when calling TEST.DBPERIOD.ODCIStatsSelectivity -- method ignored