Oracle PL/SQL 返回行数组

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19854029/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 05:21:22  来源:igfitidea点击:

Oracle PL/SQL return array of rows

oraclestored-proceduresplsql

提问by baliman

Dear Oracle Developers,

尊敬的 Oracle 开发人员:

I have searched and googled to find a solution for my problem but nothing helped me.

我已经搜索并用谷歌搜索为我的问题找到解决方案,但没有任何帮助。

Situation :

情况 :

TABLE : CUSTOMER(....);

表:客户(....);

My problem is : I want to create a stored procedure say get_customersto return an array of customer rows. I have no idea how to get this working.

我的问题是:我想创建一个存储过程,说get_customers要返回一个客户行数组。我不知道如何让这个工作。

I tried to create a type customer_rec and using a cursor to retrieve no more than maxRows

我尝试创建一个类型 customer_rec 并使用游标检索不超过 maxRows

create or replace procedure get_customers(maxRows IN NUMBER, ??? OUT ????)

How to define the OUT parameter ?

如何定义 OUT 参数?

How to retrieve the rows in the array using a cursor ?

如何使用游标检索数组中的行?

Thanks a lot

非常感谢

回答by Michael O'Neill

I would like to answer this in a way that discourages passing around arrays, when passing around cursors is a more sound approach. It doesn't exactly answer the question as posed, but it is an answer. Thinking cursors instead of thinking arrays is more efficient and thus more scalable. Also, it can be much easier code to maintain.

我想以一种不鼓励传递数组的方式来回答这个问题,因为传递游标是一种更合理的方法。它并没有完全回答所提出的问题,但它是一个答案。思考游标而不是思考数组更有效,因此更具可扩展性。此外,它可以更容易维护代码。

create table customer (
   customer_id number(2) primary key,
   customer_name varchar2(200) );

insert into customer values (1, 'Customer One');
insert into customer values (2, 'Customer Two');
insert into customer values (3, 'Customer Three');
insert into customer values (4, 'Customer Four');
insert into customer values (5, 'Customer Five');
insert into customer values (6, 'Customer Six');
insert into customer values (7, 'Customer Seven');

CREATE OR REPLACE PACKAGE cursor_not_array IS

   FUNCTION get_customers(p_max_records INTEGER, p_id_start INTEGER, p_id_end INTEGER DEFAULT NULL) RETURN SYS_REFCURSOR;

END cursor_not_array;

CREATE OR REPLACE PACKAGE BODY cursor_not_array IS

   c_max_customer_id CONSTANT NUMBER(2) := 99;

   FUNCTION get_customers(p_max_records INTEGER, p_id_start INTEGER, p_id_end INTEGER DEFAULT NULL) RETURN SYS_REFCURSOR IS
      v_result SYS_REFCURSOR;
   BEGIN
      OPEN v_result FOR
         SELECT customer_id,
                customer_name
           FROM customer
          WHERE customer_id BETWEEN p_id_start AND nvl(p_id_end, c_max_customer_id)
          ORDER BY customer_id;

      RETURN v_result;
   END;

END cursor_not_array;

回答by pablomatico

You could create a package like this:

你可以创建一个这样的包:

create or replace package customers is

  type customers_array is table of customer%rowtype index by binary_integer;

  procedure get_customers(maxRows IN NUMBER, customer_array OUT customers_array);

end customers;

create or replace package body customers is

  procedure get_customers(maxRows IN NUMBER, customer_array OUT customers_array) is
    cursor c_customers is
      select * 
      from customers;
      where rownum <= maxRows;

    i number := 1;
  begin
    for r in c_customers loop
      customer_array(i) := r;
      i := i + 1;
    end loop;
  end get_customers;

end customers;

And then call the get_customers procedure from wherever you want to...

然后从任何你想要的地方调用 get_customers 过程......

回答by Issam Ressani

You can, using the SYS_REFCURSORon your function output.

您可以在函数输出上使用SYS_REFCURSOR

回答by Guillaume

First you have to define a collection:

首先你必须定义一个集合

TYPE customers_array IS TABLE OF customer%ROWTYPE
    INDEX BY BINARY_INTEGER;

Then your procedure simply have to fetchthe result into that collection. You're procedure could be written as follow:

然后您的过程只需要将结果提取到该集合中。你的程序可以写成如下:

CREATE OR REPLACE PACKAGE your_pkg
AS

    TYPE customers_array IS TABLE OF customer%ROWTYPE
        INDEX BY BINARY_INTEGER;

    PROCEDURE get_customers(pn_max_rows    IN NUMBER,
                            pt_coustomers OUT customers_array);
END your_pkg;

CREATE OR REPLACE PACKAGE BODY your_pkg
AS

    PROCEDURE get_customers(pn_max_rows    IN NUMBER,
                            pt_coustomers OUT customers_array)
    IS
    BEGIN  
        SELECT *
          BULK COLLECT INTO pt_coustomers
          FROM customers
         WHERE rownum <= pn_max_rows;
    END get_customers;

END your_pkg;

回答by user2956499

first time create VARRAY type.

第一次创建 VARRAY 类型。

'create TYPE CUSTARRAY is VARRAY(100) OF VARCHAR2(30);'

varray limit is depends on you.

varray 限制取决于你。

then create procedure that return CUSTARRAY type parameter.

然后创建返回 CUSTARRAY 类型参数的过程。

`create 
procedure prc_get_arr(p_maxrow in number, p_customers out custarray)
as
my_cust custarray := custarray(); 
cursor c_cust is select name from CUSTOMER where rownum<p_maxrow; 
v_customer varchar2(64);
begin
open c_cust;
loop
 fetch c_cust into v_customer;
  exit when c_cust%notfound;
    my_cust.extend; 
    my_cust(my_cust.count) := v_customer; 
 end loop;
 close c_cust;
 p_customers:=my_cust;

end;`

Now call this procedure

现在调用这个程序

 DECLARE
P_MAXROW NUMBER;
p_customers custarray;
v_cnt number:=0;
 begin
P_MAXROW := 22;
prc_get_arr( p_maxrow => p_maxrow, p_customers => p_customers );
v_cnt:=p_customers.count;
for i in p_customers.first..p_customers.last loop

dbms_output.put_line('P_CUSTOMERS = ' || p_customers(i));
end loop;

end;