2016-04-10 3 views
0

Я пытаюсь получить разницу между двумя коллекциями, но каждый раз, когда вы становитесь ниже исключения. Незлая помощь. Мой пример кода также доступен ниже. Не уверен, что здесь не так ... может MULTISET EXCEPT не применяется к RECORD типам?Разница двух коллекций

PLS-00306: неверное число или типы аргументов в вызове 'MULTISET_EXCEPT_ALL'

DECLARE 
    TYPE FRND_OBJ IS RECORD 
    (
     FrndID  NUMBER, 
     JOBID  NUMBER, 
     REGIONID NUMBER, 
     COLLEGEID NUMBER 
    ); 

    TYPE FRND_LIST IS TABLE OF FRND_OBJ; 

    CURSOR c_date_rolling 
    IS 
     SELECT 1, 
      2, 
      3, 
      4 
     FROM DUAL; 

    lv_roll_date   FRND_LIST; 
    lv_roll_date_full FRND_LIST; 
    lv_roll_date_delta FRND_LIST; 
    g_error_msg   VARCHAR2 (1500); 
BEGIN 
    SELECT 5, 
      6, 
      7, 
      8 
    BULK COLLECT INTO lv_roll_date_full 
    FROM DUAL; 

    OPEN c_date_rolling; 

    FETCH c_date_rolling BULK COLLECT INTO lv_roll_date; 

    CLOSE c_date_rolling; 

    DBMS_OUTPUT.put_line ('Full Count: ' || lv_roll_date_full.COUNT); 
    DBMS_OUTPUT.put_line ('Rolling Count: ' || lv_roll_date.COUNT); 
    lv_roll_date_delta := lv_roll_date_full MULTISET EXCEPT lv_roll_date; 
    DBMS_OUTPUT.put_line (lv_roll_date_delta.COUNT); 
EXCEPTION 
    WHEN NO_DATA_FOUND 
    THEN 
     g_error_msg := 
      SUBSTR (SQLERRM, 1, 200) 
     || SUBSTR (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, 20); 
     DBMS_OUTPUT.PUT_LINE (g_error_msg); 
    WHEN OTHERS 
    THEN 
     g_error_msg := 
      SUBSTR (SQLERRM, 1, 200) 
     || SUBSTR (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, 20); 
     DBMS_OUTPUT.PUT_LINE (g_error_msg); 
END; 
/

ответ

1

Here объясняется, что вы будете нуждаться в MAP или ORDER метод. В вашем образце:

CREATE OR REPLACE TYPE frnd_obj 
    AUTHID DEFINER AS OBJECT 
(
    frndid NUMBER, 
    jobid NUMBER, 
    regionid NUMBER, 
    collegeid NUMBER, 
    MAP MEMBER FUNCTION tostring 
     RETURN VARCHAR2 
) 
/

SHOW ERRORS; 

CREATE OR REPLACE TYPE BODY frnd_obj AS 
    MAP MEMBER FUNCTION tostring 
     RETURN VARCHAR2 IS 
    BEGIN 
     RETURN TO_CHAR (frndid) || ';' || TO_CHAR (jobid) || ';' || TO_CHAR (regionid) || ';' || TO_CHAR (collegeid); 
    END tostring; 
END; 
/

CREATE TYPE FRND_LIST IS TABLE OF FRND_OBJ; 

И теперь вы можете использовать его:

DECLARE 
-- TYPE FRND_OBJ IS RECORD 
-- (
--  FrndID  NUMBER, 
--  JOBID  NUMBER, 
--  REGIONID NUMBER, 
--  COLLEGEID NUMBER 
-- ); 

-- TYPE FRND_LIST IS TABLE OF FRND_OBJ; 

    CURSOR c_date_rolling 
    IS 
     SELECT FRND_OBJ(1, 
      2, 
      3, 
      4) 
     FROM DUAL; 
--  union all 
--  SELECT FRND_OBJ(5, 
--   6, 
--   7, 
--   8) 
--  FROM DUAL; 

    lv_roll_date   FRND_LIST; 
    lv_roll_date_full FRND_LIST; 
    lv_roll_date_delta FRND_LIST; 
    g_error_msg   VARCHAR2 (1500); 
BEGIN 
    SELECT FRND_OBJ(5, 
      6, 
      7, 
      8) 
    BULK COLLECT INTO lv_roll_date_full 
    FROM DUAL; 

    OPEN c_date_rolling; 

    FETCH c_date_rolling BULK COLLECT INTO lv_roll_date; 

    CLOSE c_date_rolling; 

    DBMS_OUTPUT.put_line ('Full Count: ' || lv_roll_date_full.COUNT); 
    DBMS_OUTPUT.put_line ('Rolling Count: ' || lv_roll_date.COUNT); 
    lv_roll_date_delta := lv_roll_date_full MULTISET EXCEPT ALL lv_roll_date; 
    DBMS_OUTPUT.put_line (lv_roll_date_delta.COUNT); 
EXCEPTION 
    WHEN NO_DATA_FOUND 
    THEN 
     g_error_msg := 
      SUBSTR (SQLERRM, 1, 200) 
     || SUBSTR (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, 20); 
     DBMS_OUTPUT.PUT_LINE (g_error_msg); 
    WHEN OTHERS 
    THEN 
     g_error_msg := 
      SUBSTR (SQLERRM, 1, 200) 
     || SUBSTR (DBMS_UTILITY.FORMAT_ERROR_BACKTRACE, 20); 
     DBMS_OUTPUT.PUT_LINE (g_error_msg); 
END; 
/
+2

Избили меня к нему на 15 секунд * 8-) небольшое расширение, чтобы ответить на поставленный вопрос, фактический: нет, вы можете» t использовать типы записей, поскольку они не могут иметь методы карты/порядка. Вы также можете использовать тип объекта, который не имеет карты/порядка, но тогда вам нужно «выбрать мультимножество ... в ... из двойного». И вы не можете использовать типы записей в SQL, поэтому для этого требуется тип объекта. Но 'FRND_LIST' может быть табличным типом PL/SQL - он работает в любом случае. –

+0

благодаря вам, вы узнали что-то новое об объектах. Ссылка «ЗДЕСЬ», которую разделил @Mottor, была очень проницательной! –

Смежные вопросы