我将数组传递给PL / SQL包函数。我这样做是为了在具有IN子句的函数内的查询中使用这个数组。
我的包裹声明如下:
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 :(得分:2)
您无法在sql查询中查询plsql中声明的类型,因为sql引擎无法识别它。
您的第一个示例有效,因为您已在数据库中声明了类型numarr1,而类型为selected_pkg.num_array在包中声明。
好总结here
答案 1 :(得分: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;
/
...并且还使用模式级别类型调用:
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来说它们是不同的并且不兼容。