从procedure返回多行,选择语句PL / SQL

时间:2017-03-26 02:28:49

标签: oracle stored-procedures plsql spatial-query oracle-spatial

这是一个匿名块的过程部分,它从中获取参数pID,parcel_id。我的问题是select语句用于查找和显示触摸查询包的所有宗地,当我输入时,它在普通的SQL查询中完美地运行,

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.但是,当我在程序中执行此操作时,我要么得到'TOO Many Rows Error',要么我尝试添加'And Rownum< 2'它工作正常,但没有显示所有关系,即它贯穿并显示每个包裹的一个关系。我能做些什么来改善这个吗?我一直在阅读网站上的其他帖子,有参考游标的参考,但我不知道这些适用于这里。非常感谢。

procedure Payx (pID number )is 

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

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;

3 个答案:

答案 0 :(得分:0)

由于尝试OUT多个值,您需要使用ether Cursor或者使用集合的hlp。希望这会有所帮助。

{{1}}

答案 1 :(得分:0)

如@Muhammad Muazzam所述,由于查询返回multiple rows,您需要collection一次保存记录,或者loop通过选择并保留您声明的变量中的记录。我告诉你如何使用RECORD来做到这一点。

create or replace procedure payx (pid   number) 
is
   --Created a record by bundling all your single defined variables  
     type xx is RECORD
     (
         vardistrict                   parking.district_id%type,
         vid                           parking.parcel_id%type,
         vqed                          parking.parcel_id%type,
         varrel                        varchar2 (20);

     );

     type var is table of xx index by pls_integer;

     var1 var;       

begin
     select target.district_id,
            target.parcel_id,
            query.parcel_id,
            sdo_geom.relate (target.geom,
                             'determine',
                             query.geom,
                             0.05
                            ) relationship
       bulk collect into var1
       from parking target,
            parking query
      where query.parcel_id = pid
        and sdo_relate (target.geom,
                        query.geom,
                        'mask=TOUCH'
                       ) = 'TRUE' ;

      for i in 1..var1.count
      loop                       
       dbms_output.put_line (   var1 (i).vardistrict
                            || var1 (i).vid
                            || var1 (i).vqed
                            || var1 (i).varrel);

      end loop;
end payx;

答案 2 :(得分:0)

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

几乎所有在应用程序中使用的典型SELECT语句都会返回多个结果 - 可能会有很多结果。然后,应用程序需要准备好一个接一个地处理这些结果。这样做的方式取决于编写应用程序的语言。例如,对于Java,查询返回一个ResultSet对象,您可以使用其next()方法迭代该对象。 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';

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'

返回sdo_geom.relate(target.geom, 'determine', query.geom, 0.05)是没有意义的,因为你检查了TOUCH关系:结果将永远是TOUCH。它只会增加运行查询的CPU成本。