в нормальной функции оракула: ORA-06531: ссылка на неинициализированную коллекцию - PullRequest
0 голосов
/ 24 мая 2018

Моя функция выполняется отлично, но при ее объявлении отображаются ошибки.Код:

set serveroutput on

create or replace type myarray is varray(10000) of number;

create or replace function T_Bill (cus_id in integer) return number as
    t_cost number:=0;
    n integer;   
    bk myarray;
    pr myarray;
    q myarray;   
begin
    select count(book_id) into n from issue where cust_id=cus_id;
    select book_id,quantity BULK COLLECT into bk,q from issue where cust_id=cus_id;
    for i in 1..n
    loop
        select price into pr(i) from book where ISBN=bk(i);
        DBMS_OUTPUT.PUT_LINE(bk(i)||' '||q(i));
        t_cost:=pr(i);
    end loop;

    return t_cost;
end;
/

И я объявляю это так:

declare 
 x integer:=1;
 begin
 DBMS_OUTPUT.PUT_LINE(T_Bill(x));
 end;
 /

И ошибки:

ORA-06531: Reference to uninitialized collection
ORA-06512: at "R1507090.T_BILL", line 12
ORA-06512: at line 4

Заранее спасибо.

1 Ответ

0 голосов
/ 24 мая 2018

Вы пытаетесь установить pr(i), когда не инициализировали коллекцию.Кроме того, вы перезаписываете t_cost каждую итерацию цикла.

create or replace function T_Bill (
  cus_id in integer
)
  return number
as
  t_cost number:=0;
  bk myarray;
  pr myarray;
  q  myarray;   
begin
  select book_id,quantity
  BULK COLLECT into bk,q
  from issue
  where cust_id=cus_id;

  pr := myarray();               -- Initialise the collection
  pr.EXTEND( bk.COUNT );         -- Set the size of the collection

  FOR i IN 1..bk.COUNT LOOP
    select price into pr(i) from book where ISBN=bk(i);
    DBMS_OUTPUT.PUT_LINE(bk(i)||' '||q(i));
    t_cost:= t_cost + pr(i);
  END LOOP;

  return t_cost;
end;
/

Однако самое простое решение - использовать объединение и заполнить все коллекции одновременно (при условии, что существует множествоодно отношение от выпуска к книге по первичному ключу ISBN:

create function T_Bill (
  cus_id in ISSUE.CUST_ID%TYPE
)
  return number
as
    t_cost number :=0;
    bk myarray;
    pr myarray;
    q  myarray;   
begin
  select i.book_id,
         i.quantity,
         b.price
  BULK COLLECT into
         bk,
         q,
         pr
  from   issue i
         LEFT OUTER JOIN book b     -- INNER JOIN?
         ON ( i.book_id = b.ISBN )
  where  i.cust_id = cus_id;

  FOR i IN 1..n LOOP
    DBMS_OUTPUT.PUT_LINE(bk(i)||' '||q(i));
    t_cost:= t_cost + pr(i);
  END LOOP;

  return t_cost;
end;
/
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...