2013-05-01 106 views
0

我將數組傳遞給PL/SQL包函數。我這樣做是爲了在具有IN子句的函數內的查詢中使用這個數組。將數組傳遞給Oracle函數

我的包的聲明如下:

create or replace 
PACKAGE selected_pkg IS 

    TYPE NUM_ARRAY IS TABLE OF NUMBER; 

    FUNCTION get_selected_kml(
     in_layer  IN NUMBER, 
    in_id  IN NUMBER, 
     in_feature_ids IN selected_pkg.NUM_ARRAY, 
     in_lx   IN NUMBER, 
     in_ly   IN NUMBER, 
     in_ux   IN NUMBER, 
     in_uy   IN NUMBER 
    ) 
    RETURN CLOB; 

END selected_pkg; 

在我的PL/SQL函數,我一槍一查詢像下面

select a.id, a.geom from Table_FIELD a where a.id in (select * from table (in_feature_ids)) and sdo_filter(A.GEOM,mdsys.sdo_geometry(2003,4326,NULL,mdsys.sdo_elem_info_array(1,1003,3), mdsys.sdo_ordinate_array(0,57,2.8,59)),'querytype= window') ='TRUE' 

同樣的查詢運行正常,如果我從匿名塊運行像

CREATE TYPE num_arr1 IS TABLE OF NUMBER; 

declare 
    myarray num_arr1 := num_arr1(23466,13396,14596); 
BEGIN 
    FOR i IN (select a.id, a.geom from Table_FIELD a where a.id in (select * from table (myarray)) and sdo_filter(A.GEOM,mdsys.sdo_geometry(2003,4326,NULL,mdsys.sdo_elem_info_array(1,1003,3), mdsys.sdo_ordinate_array(0,57,2.8,59)),'querytype= window') ='TRUE' 
    loop 
     dbms_output.put_line(i.id); 
    end loop; 
end; 

如果我試着通過調用函數來運行它如下

--Running function from passing array for IDs 
declare 
    result CLOB; 
    myarray selected_pkg.num_array := selected_pkg.num_array(23466,13396,14596); 
begin 
    result:=SELECTED_PKG.get_selected_kml(3, 19, myarray, 0.0,57.0,2.8,59); 
end; 

我收到錯誤

ORA-00904: "IN_FEATURE_IDS": invalid identifier 

可能有人請幫助我理解它的原因是什麼?

謝謝你,艾倫

+0

亞歷克斯,是的,我在上面的問題中得到了修正(在複製粘貼時引起的錯誤)。但是我正確運行它。 – AlanShar 2013-05-01 07:42:19

回答

2

您不能查詢在一個SQL查詢PLSQL聲明的類型,因爲SQL引擎無法識別它。

您的第一個示例工作原因是您已在數據庫中聲明瞭numarr1類型,而selected_pkg.num_array類型是在包中聲明的。

很好的總結here

+0

Stevo,你能否建議我如何實現功能? – AlanShar 2013-05-01 09:01:48

+0

@AlanShar查看Alex Poole的回答。 – 2013-05-01 09:14:46

2

我不能完全重新創建你得到的錯誤;匿名塊沒有引用in_feature_ids,並且該包只應報告,如果它不能在編譯時而不是在運行時識別它,除非你使用動態SQL。不能看到函數體,我不知道這是如何發生的。

但是,您不能在SQL語句中使用PL/SQL定義的類型。在某些時候table(in_feature_ids)會出錯;當我嘗試時,我得到了一個ORA-21700,這對我來說是一個新的,我期望ORA-22905。不管是什麼錯誤,你必須使用在架構級別定義,而不是包中的一個類型,所以這將工作(跳躍的簡潔空間的東西):

CREATE TYPE num_array IS TABLE OF NUMBER; 
/

CREATE OR REPLACE PACKAGE selected_pkg IS 
    FUNCTION get_selected_kml(
     in_layer  IN NUMBER, 
     in_id   IN NUMBER, 
     in_feature_ids IN NUM_ARRAY, 
     in_lx   IN NUMBER, 
     in_ly   IN NUMBER, 
     in_ux   IN NUMBER, 
     in_uy   IN NUMBER 
    ) RETURN CLOB; 
END selected_pkg; 
/

CREATE OR REPLACE PACKAGE BODY selected_pkg IS 
    FUNCTION get_selected_kml(
     in_layer  IN NUMBER, 
     in_id   IN NUMBER, 
     in_feature_ids IN NUM_ARRAY, 
     in_lx   IN NUMBER, 
     in_ly   IN NUMBER, 
     in_ux   IN NUMBER, 
     in_uy   IN NUMBER 
    ) RETURN CLOB IS 
    BEGIN 
     FOR i IN (select * from table(in_feature_ids)) LOOP 
      DBMS_OUTPUT.PUT_LINE(i.column_value); 
     END LOOP; 
     RETURN null; 
    END get_selected_kml; 
END selected_pkg; 
/

...並調用也使用模式-level類型:

set serveroutput on 
declare 
    result CLOB; 
    myarray num_array := num_array(23466,13396,14596); 
begin 
    result:=SELECTED_PKG.get_selected_kml(3, 19, myarray, 0.0,57.0,2.8,59); 
end; 
/

23466 
13396 
14596 

PL/SQL procedure successfully completed. 

另外請注意,您必須使用完全相同的類型,而不僅僅是一個看起來一樣,所討論in a recent question。例如,您將無法使用num_arr1類型的變量調用您的函數;它們表面上看起來是一樣的,但對於Oracle來說它們是不同的並且不兼容。