2017-06-28 481 views
1

我是oracle新技術,請幫幫我ORA-30626:不支持遠程對象類型的函數/過程參數

我找不到答案。我的任務是通過通過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([email protected]_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([email protected]_link(param1,param2)) 

SELECT * FROM TABLE(myfun_loc(param1,param2)) 
union all 
SELECT * FROM TABLE([email protected]_link(param1,param2,parm3)); 

--not工作相同的錯誤消息如上

我試圖創建視圖在遠程DB2但沒有數據被顯示作爲我的功能需要傳遞,這是不可能通過參數在參數視圖。

PS對不起我的英語不好

+1

的[調用存儲功能在Oracle在數據庫中鏈接(即返回一個用戶定義類型的數組)](可能的複製https://stackoverflow.com/questions/7245995 /調用一個存儲函數返回一個用戶定義類型的orac) – XING

+0

嗨,你有沒有檢查我的**編輯**的答案? – hmmftg

+0

是的,我沒有檢查你編輯的答案,我試圖用你的例子在我的問題,即使艱難,我仍然不成功。 –

回答

0

我個人處理這種情況,你最好的辦法是將序列號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; 
+0

非常感謝你的答案hmmftg,正如我上面提到的這是我第一次在oracle中,你能給我簡單的例子代碼爲你​​的答案。 –

相關問題