1

亲爱的 Oracle 开发人员,

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

情况 :

表:客户(....);

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

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

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

如何定义 OUT 参数?

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

非常感谢

4

5 回答 5

3

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

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;
于 2013-11-08T21:15:59.493 回答
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 过程......

于 2013-11-08T11:03:32.570 回答
1

第一次创建 VARRAY 类型。

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

可变数组限制取决于你。

然后创建返回 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;
于 2013-11-08T10:26:46.760 回答
1

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

于 2017-12-06T10:16:30.543 回答
1

首先你必须定义一个集合

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

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

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;
于 2017-12-08T23:38:37.017 回答