ORA-30626: параметры функции/процедуры удаленных типов объектов не поддерживаются

Я новичок в технологии Oracle, пожалуйста, помогите мне.

Я не мог найти ответ, какие были. Моя задача - запустить две функции, передав параметр через dblink. У меня есть две одинаковые функции на db1 и db2, которые расположены на двух разных виртуальных машинах в Hyper v, мне удалось создать между ними dblink, но когда я запрашиваю следующую команду, отображается указанное выше сообщение об ошибке.

SELECT /*+ parallel(4) */ *
FROM TABLE(my_fun(CURSOR(SELECT PDBID, STRUCTURE FROM PROTEINS
WHERE PDBID= '1n6h'),
  CURSOR(SELECT PDBID, STRUCTURE FROM PROTEINS WHERE PDBID BETWEEN
  '1n6h' AND '1n6h'), PRINT => 0, ALGORITHM_TYPE=>2, CHAIN2=>'A'))
 UNION ALL
  SELECT /*+ parallel(4) */ *
  FROM TABLE(my_fun@test_link2(CURSOR(SELECT PDBID, STRUCTURE FROM
   PROTEINS WHERE PDBID= '1n6h'),
   CURSOR(SELECT PDBID, STRUCTURE FROM PROTEINS WHERE PDBID BETWEEN
   '1n6n' AND '1n6n'), PRINT => 0, ALGORITHM_TYPE=>2, CHAIN2=>'A'));

Это то, что я создал как в db1, так и в db2, я пытался создать функцию-оболочку в обеих базах данных, но я все еще не могу получить данные через dblink.

CREATE OR REPLACE
 type my_record force is object (
   QPDBID varchar2(8),
   DBPDBID varchar2(8));
/

CREATE OR REPLACE TYPE MY_TYPE AS TABLE OF
my_record
/
CREATE OR REPLACE FUNCTION myfun_rem(qpdb in varchar2,dbpdbid1 in varchar2)
    RETURN MY_TYPE
  AS
    v_my_tst MY_TYPE;
  BEGIN
SELECT MY_RECORD(QPDBID ,DBPDBID)
  BULK COLLECT INTO  v_my_tst
FROM
  (SELECT QPDBID, DBPDBID FROM TABLE(my_fun(CURSOR(SELECT PDBID,
    STRUCTURE FROM PROTEINS WHERE PDBID= QPDBID ),
      CURSOR(SELECT PDBID, STRUCTURE FROM PROTEINS WHERE PDBID BETWEEN
    QPDBID  AND QPDBID ), PRINT => 0, ALGORITHM_TYPE=>2, CHAIN2=>'A')));
    RETURN  v_my_tst;
    EXCEPTION
    WHEN OTHERS THEN
    v_my_tst.DELETE;
    RETURN  v_my_tst;
  END;
  /

 SELECT * FROM  TABLE(myfun_rem(param1,param2)); --this works locally but not remotely (select * from table(myfun_rem@test_link(param1,param2))

SELECT * FROM  TABLE(myfun_loc(param1,param2))
union all
SELECT * FROM  TABLE(myfun_rem@test_link(param1,param2,parm3));

--не работает то же сообщение об ошибке, что и выше

Я попытался создать представление в удаленной базе данных db2, но данные не отображаются, так как моя функция требует передачи параметров, что невозможно для передачи параметра в представление.

p.s. простите за мой плохой английский


person S.Ora    schedule 28.06.2017    source источник
comment
Привет, ты проверил мое редактирование в ответе?   -  person hmmftg    schedule 08.07.2017
comment
да, я проверил ваш отредактированный ответ, я пытался использовать ваш пример в своей проблеме, даже если я все еще не добился успеха.   -  person S.Ora    schedule 09.07.2017


Ответы (1)


Я лично имел дело с этой ситуацией, ваш лучший способ - сериализовать таблицу объектов в db1 и преобразовать их обратно в таблицу объектов в db2.

1- ваш объект должен иметь функцию сериализации, которая преобразует его поля в строку.

2- ваш объект должен иметь конструктор с возможностью инициализировать новый объект из строки.

Например:

CREATE OR REPLACE TYPE CAR AS OBJECT
    (NAME VARCHAR2 (36),
     MODEL NUMBER,
     MEMBER FUNCTION SERIALIZE
         RETURN VARCHAR2,
     MEMBER FUNCTION DUMP
         RETURN VARCHAR2,
     STATIC FUNCTION DESRIALIZE (DATA IN VARCHAR2)
         RETURN CAR);

CREATE OR REPLACE TYPE BODY CAR
IS
    MEMBER FUNCTION SERIALIZE
        RETURN VARCHAR2
    IS
    --YOU HAVE TO CONVERT ALL FIELDS(TYPE MEMBERS) TO STRING HERE(USE FIELD SEPARATOR LIKE ',')
    BEGIN
        RETURN NAME || ',' || TO_CHAR (MODEL, 'FM9999');
    END;

    MEMBER FUNCTION DUMP
        RETURN VARCHAR2
    IS
    BEGIN
        RETURN    'CAR NAME: ['
               || NAME
               || ']'
               || CHR (10)
               || CHR (13)
               || 'CAR MODEL: ['
               || TO_CHAR (MODEL, 'FM9999')
               || ']';
    END;

    STATIC FUNCTION DESRIALIZE (DATA IN VARCHAR2)
        RETURN CAR
    IS
        --DO EXACTLY REVERSE OF SERIALIZATION
        NEW_CAR   CAR;
    BEGIN
        NEW_CAR :=
            CAR (SUBSTR (DATA, 1, INSTR (DATA, ',') - 1),
                 TO_NUMBER (SUBSTR (DATA, INSTR (DATA, ',') + 1)));
        --TO_NUMBER FUNCTION IS NOT REALLY NEEDED HERE, ORACLE DOES THE CAST FOR YOU, BUT I TRIED  TO MAKE IT MORE UNDERSTANDABLE
        RETURN NEW_CAR;
    END;
END;

DECLARE
    MY_CAR     CAR;
    V_STRING   VARCHAR2 (64);
    DUP_CAR    CAR;
BEGIN
    MY_CAR := CAR ('PEYKAN', 1350);
    DBMS_OUTPUT.PUT_LINE (MY_CAR.DUMP ());
    V_STRING := MY_CAR.SERIALIZE ();--You should do this in db 1 and send string(varchar2) to db2
    DUP_CAR := CAR.DESRIALIZE (V_STRING);--In db2, you will do this to get the object from string
    DBMS_OUTPUT.PUT_LINE (DUP_CAR.DUMP ());
END;
person hmmftg    schedule 03.07.2017
comment
Большое спасибо за ответ, хммфтг, как я уже упоминал выше, это мой первый раз в оракуле, не могли бы вы дать мне простой пример кода для вашего ответа. - person S.Ora; 04.07.2017