【问题标题】:Oracle PL/SQL return array of rowsOracle PL/SQL 返回行数组
【发布时间】:2013-11-20 03:59:16
【问题描述】:

尊敬的 Oracle 开发人员,

我已经搜索和谷歌搜索以找到解决我问题的方法,但没有任何帮助。

情况:

表:客户(....);

我的问题是:我想创建一个存储过程说get_customers 来返回一个客户行数组。我不知道如何让它发挥作用。

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

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

OUT参数如何定义?

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

非常感谢

【问题讨论】:

  • 我已经搜索和谷歌搜索以找到解决我问题的方法,但没有任何帮助。你看过这个stackoverflow.com/q/1170548/1920232 吗?
  • 你打算在哪里使用那个数组?在另一个存储过程中?在 Java 中?

标签: oracle stored-procedures plsql


【解决方案1】:

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

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;

【讨论】:

    【解决方案2】:

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

    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;
    

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

    【讨论】:

    • 什么是 mexa_expedientes ?
    • 我的意思是客户表。我已经编辑了!很抱歉!
    【解决方案3】:

    第一次创建 VARRAY 类型。

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

    varray 限制取决于你。

    然后创建返回 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;`
    

    现在调用这个过程

     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;
    

    【讨论】:

      【解决方案4】:

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

      【讨论】:

        【解决方案5】:

        首先你必须定义一个collection

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

        然后您的程序只需要将fetch 的结果放入该集合中。 你的程序可以写成如下:

        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;
        

        【讨论】:

          猜你喜欢
          • 2015-04-06
          • 2012-10-31
          • 1970-01-01
          • 1970-01-01
          • 2021-04-28
          • 1970-01-01
          • 1970-01-01
          • 2013-05-06
          • 1970-01-01
          相关资源
          最近更新 更多