Oracle 从过程返回多行,选择语句PL/SQL

Oracle 从过程返回多行,选择语句PL/SQL,oracle,stored-procedures,plsql,spatial-query,oracle-spatial,Oracle,Stored Procedures,Plsql,Spatial Query,Oracle Spatial,这是匿名块的过程部分,它从中获取参数pID,parcel_id。我的问题是select语句用于查找和显示与查询地块接触的所有地块,当我输入 select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship from Parking target, Parking query whe

这是匿名块的过程部分,它从中获取参数pID,parcel_id。我的问题是select语句用于查找和显示与查询地块接触的所有地块,当我输入

select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
    from Parking target, Parking query
    where query.parcel_id = 68
    and  target.district_id = 1
    and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE';

该示例返回五行,其中包含5个与地块68接触的不同地块。但是,当我在过程中执行此操作时,我要么得到“太多行错误”,要么如果我尝试添加“和Rownum,因为它们试图输出多个值,您需要使用ether Cursor或集合的hlp。希望这有帮助

procedure Payx (pID number,
                p_ref_out OUT sys_refcursor )is 

  varDistrict Parking.District_id%type;
  vID Parking.parcel_id%type;
  vQED Parking.parcel_id%type;
  varRel varchar2(20);
  begin

OPEN p_ref_out FOR
select target.district_id, target.parcel_id,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
      into varDistrict
           vID,
           vQED,
           varRel
      from Parking target, Parking query
      where query.parcel_id = pID
      and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE';
    ---  and rownum <2;
    ---  dbms_output.put_line('')

  end Payx;

正如@Muhammad Muazzam所提到的,由于查询返回多行,因此您需要一个集合来一次性保存记录,或者您可以在声明的变量中循环选择并保存记录。我将向您展示如何使用记录来执行此操作

问题是:你想对结果做什么

几乎所有应用程序中使用的典型SELECT语句都会返回多个结果,可能会返回很多结果。然后,应用程序需要准备好一个接一个地处理这些结果。完成此操作的方式取决于应用程序所用的语言。例如,对于Java,查询返回一个ResultSet对象,您可以使用它的下一个方法对其进行迭代。Python使用类似的技术

在PL/SQL中,只需使用for循环。无需使用显式游标:

for t in (
  select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
  from Parking target, Parking query
  where query.parcel_id = 68
  and  target.district_id = 1
  and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE'
)
loop
   -- process the results here
end loop;
在循环内部,通过在每个结果中使用循环变量t作为前缀来引用返回的列。例如:

  dbms_output.put_line ('district_id='||t.district_id);
显然,我认为应用程序的目的不是在sqlplus中打印结果。你可以对结果进行计算,把它们写到另一张表上

现在,如果您的目的是将结果保存在某个表中以供以后处理,则只需执行以下操作:

create table query_results as 
select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
from Parking target, Parking query
where query.parcel_id = 68
and  target.district_id = 1
and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE';

那么您使用什么应用程序语言呢?你对你的查询结果做了什么

编辑:

您可以通过编写以下内容稍微简化语法:

and  sdo_touch(target.geom, query.geom) = 'TRUE'

返回sdo_geom.relatetarget.geom,'determine',query.geom,0.05是没有意义的,因为您检查了触摸关系:结果将始终是触摸。这只会增加运行查询的CPU成本。

您需要使用游标。当您尝试在数据类型的单个维度声明变量中放置多行时,可能会出现重复太多行的错误。当您试图通过过程/函数返回时,它不会出现。另外,OP的目的不是将resultset作为OUT参数返回。我的意思是使用游标或集合来处理这种情况。在我的回答中,OUT的意思是:只在标量变量中放入多个值。希望你能理解。谢谢,我尝试了这个方法,它似乎已经成功了,很抱歉我的回复太晚了。我花了一段时间才弄明白为什么它会起作用,所以我知道以后会出现这个问题。谢谢你的回复,我最终使用了这个答案和上面的答案的组合。出于某种原因,我认为这是我的数据集,当我试图进一步处理时,循环选项一直为某些行抛出“未找到数据”。我正在使用函数计算大小并显示结果。但是,如果没有一些问题行,这个解决方案会更好,而且数据库太大,无法找到所有问题行。从好的方面来说,我已经学会了如何在没有光标的情况下循环,所以谢谢你。
create table query_results as 
select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
from Parking target, Parking query
where query.parcel_id = 68
and  target.district_id = 1
and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE';
insert into query results
select target.district_id, target.parcel_id ,query.parcel_id, sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)Relationship
from Parking target, Parking query
where query.parcel_id = 68
and  target.district_id = 1
and  sdo_relate(target.geom, query.geom, 'mask=TOUCH') = 'TRUE';
and  sdo_touch(target.geom, query.geom) = 'TRUE'