Return 来自过程的多行,select 语句 PL/SQL

Return multiple rows from procedure , select statement PL/SQL

这是匿名块的过程部分,它从中获取参数 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';

那个例子 returns 五行有 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;

由于试图输出多个值,您需要使用以太游标或使用集合的帮助。希望这有帮助。

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 所述,由于查询返回 multiple rows,您需要 collection 一次性保存记录,或者您可以 loop 通过 select 并将记录保存在您声明的变量中。我将向您展示如何使用 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;

真正的问题是:您想对结果做什么?

应用程序中使用的几乎所有典型 SELECT 语句 return 多个结果 - 可能有很多。然后,应用程序需要准备好一个接一个地处理这些结果。完成此操作的方式取决于您的应用程序编写的语言。例如,对于 Java,查询 return 是一个 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;

在循环内,通过在循环变量前加上前缀 return 来引用每个结果中编辑的列(此处为 t)。例如:

  dbms_output.put_line ('district_id='||t.district_id);

显然我想你的应用程序的目的不是在 sqlplus 中打印出结果。您可以对结果进行计算,将它们写到另一个 table ...

现在,如果您的目的是将结果保存在一些 table 中以供以后处理,那么就这样:

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'

并且 returning sdo_geom.relate(target.geom, 'determine', query.geom, 0.05) 是没有意义的,因为您检查了 TOUCH 关系:结果将始终是 TOUCH。它只是增加了 运行 查询的 CPU 成本。