【问题标题】:Returning Count and Resultset from a single stored procedure从单个存储过程返回计数和结果集
【发布时间】:2010-11-24 22:15:27
【问题描述】:

我对 Oracle 的存储过程还很陌生。我希望能够在一个存储过程中同时返回酒店数量和酒店名称。问题是我不知道从哪里开始。任何帮助将不胜感激。

SELECT COUNT(HNAME) FROM HOTELS; //returns 'There are 30 hotels' 
SELECT HNAME FROM HOTELS; //returns a table of 30 hotel names

【问题讨论】:

  • 有多少家酒店?如果只有 30,则只返回结果集,并计入客户端代码。仅当您需要分页(即无法将完整数据返回给客户端)时才开始担心服务器端计数。

标签: sql oracle stored-procedures


【解决方案1】:

你可以一次获得它:

SELECT HNAME, COUNT(*) OVER () FROM HOTELS;

返回:

HNAME    COUNTOVER
=======  =========
bla             30
daa             30
gaa             30
...

或者,如果您在 PL/SQL 中将列表批量收集到内存数组中,则可以使用 COUNT 函数从数组中获取计数。

【讨论】:

    【解决方案2】:

    只需向您展示示例(如果您想要的只是方法,不一定是每个测试用例的原因),您就可以非常简单地获得结果。我整理了一个测试用例给你看

    create table HOTELS (hname varchar2(50) ) ; --create table for test
    
    declare  --put data into it for test
    i number ;
    begin
      for i in 1 .. 50 loop
        insert into hotels (hname) values('Hotel: ' || i); 
      end loop ;
      commit ;
    end ;
    /
    

    --现在创建一个过程并显示结果

    set serveroutput on
    declare
     resultQuery sys_refcursor ;
     countOfHotels number ;
     hotelName HOTELS.hname%type ;
     procedure getHotels(HotelCount out number ,
                                HotelList  out nocopy sys_refcursor) is
                                begin
                                    select count(*) 
                                      into HotelCount
                                      FROM HOTELS ;
    
                                      open HOTELLIST For
                                       select * 
                                          from HOTELS ;
                                end getHotels;
    begin
      getHotels(countOfHotels, resultQuery) ;
    
            dbms_output.put_line('Count Of Hotels ' || countOfHotels);
          loop
             fetch resultQuery into hotelName;
             exit when resultQuery%notfound;
             dbms_output.put_line('Found Hotel: ' || hotelName);
          end loop;
    
    end ;
    

    现在来看结果:

    /**
    results
    Count Of Hotels 50
    Found Hotel: Hotel: 1
    Found Hotel: Hotel: 2
    Found Hotel: Hotel: 3
    Found Hotel: Hotel: 4
    Found Hotel: Hotel: 5
    ....
    
    **/
    

    但是所有的工作都在这里完成:

     procedure getHotels(HotelCount out number ,
                                HotelList  out nocopy sys_refcursor) is
        begin
            select count(*) 
              into HotelCount
              FROM HOTELS ;
    
              open HOTELLIST For
               select * 
                  from HOTELS ;
        end getHotels;
    

    选择变量,然后打开 REFCURSOR FOR 游标

    【讨论】:

      【解决方案3】:
      select 'count', to_char(COUNT(HNAME)) FROM HOTELS
      union
      select 'Hotel Name', HNAME FROM HOTELS;
      

      【讨论】:

        【解决方案4】:

        有很多选择。通常我最喜欢 Thilo 的想法,因为大多数情况并不需要知道返回的确切行数,因此每次查询运行时都计算它们的成本是不值得的。

        如果将行数限制在不那么重要的地方,您可以执行已经给出的任何选项,或者您也可以返回包含酒店名称的集合,然后使用 .COUNT 属性您返回的集合的数量来确定计数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-03-27
          • 2011-04-22
          • 2011-03-20
          • 2013-10-06
          相关资源
          最近更新 更多