Как исправить «Ошибка (9,7): PL / SQL: ORA-00947: недостаточно значений» в функции? - PullRequest
0 голосов
/ 07 мая 2019

Я пытаюсь получить общую комиссию за каждого сотрудника Sale и сохранить ее в функции, чтобы включить ее в процедуру. Когда я добавляю рабочий оператор выбора (включая три таблицы), я получаю Error(9,20): PL/SQL: ORA-00947: not enough values. Я думаю, потому что тип данных возвращает только число в этой функции, но таблица содержит другие типы данных varchar, которые вызывают эту проблему.

Я попытался удалить некоторые столбцы, имеющие тип данных varchar2, но результат был неправильным.

Ниже мой вымышленный код:

create or replace FUNCTION get_total_commission return number 
IS
  v_total_commission;
--
begin
      select
      sale_id, sale_acct,sale_name, sum(commission) as total_commission      
      into v_total from invoice_tbl invoice join commission_tbl commission
      on invoice.id = commission.id join sale_tbl sale on sale.id = commssion.id
      where invoice.refnr is null;
  return to_char(v_total, 'FM99999.00');
EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line('err: ' ||SQLERRM);  

end get_total_commission; 

Это будет функция, которая будет отображать общую сумму комиссионного вознаграждения, получаемого каждым сотрудником Sale.

Ответы [ 2 ]

1 голос
/ 07 мая 2019

общая сумма комиссионного вознаграждения, получаемого каждым сотрудником по продажам

Похоже, что возвращение одного числа, лишенного идентифицирующих характеристик, не является решением, которое вам нужно.Вам нужен набор результатов.Лично это выглядит лучше для представления, чем для функции, но если вы хотите обернуть запрос в функцию, вот как это сделать:

-- obviously correct these data types to fit your actual needs
create or replace type commission_t as object(
    sale_id varchar2(30)
    , acct_id varchar2(30)
    , sale_name varchar2(48)
    , total_commission_number
);
/

create or replace type commission_nt as table of commission_t; 
/

create or replace FUNCTION get_total_commission return commission_nt
IS
    return_value commission_nt;
begin
      select commission_t(
                   sale_id, sale_acct,sale_name, sum(commission) )   
      bulk collect into return_type
      from invoice_tbl invoice 
           join commission_tbl commission on invoice.id = commission.id 
          join sale_tbl sale on sale.id = commssion.id
      where invoice.refnr is null
      group by sale_id, sale_acct,sale_name
      ;

     return return_value;  

end get_total_commission;

И запросить его следующим образом:

select * from table (get_total_commission);

Есть разные неровности.Например, он не будет работать хорошо, если ваш набор результатов огромен (что, очевидно, зависит, но, скажем, более 5000-10000 строк).


Если вы действительно просто хотите получить общую комиссию за одну продажутогда вам нужно ограничить запрос SALE_ID - и передать его в качестве параметра:

create or replace FUNCTION get_total_commission 
    (p_sale_id in sale.id%type)
    return number 
IS
  v_total_commission number;
--
begin

      select
      sum(commission) as total_commission      
      into v_total_commission 
      from invoice_tbl invoice 
           join commission_tbl commission on invoice.id = commission.id 
           join sale_tbl sale on sale.id = commssion.id
      where sale.id = p_sale_id
      and invoice.refnr is null;

      return v_total_commission ;

end get_total_commission; 
1 голос
/ 07 мая 2019

Вам необходимо использовать локальную переменную, к которой возвращаются все четыре столбца в списке SELECT. А из-за преобразования в символьный тип для функции нужно возвращать значение строкового типа вместо числового.

SQL> SET SERVEROUTPUT ON;
SQL> CREATE OR REPLACE FUNCTION get_total_commission RETURN varchar2 IS
  v_total_commission commission_tbl.commission%type;
  v_sale_id          sale_tbl.sale_id%type;
  v_sale_acct        sale_tbl.sale_acct%type;
  v_sale_name        sale_tbl.sale_name%type;
BEGIN
  select sale_id, sale_acct, sale_name, sum(commission) as total_commission
    into v_sale_id, v_sale_acct, v_sale_name, v_total
    from invoice_tbl invoice
    join commission_tbl commission
      on invoice.id = commission.id
    join sale_tbl sale
      on sale.id = commssion.id
   where invoice.refnr is null;
  return to_char(v_total, 'FM99999.00');
EXCEPTION
  WHEN OTHERS THEN
    dbms_output.put_line('err: ' || SQLERRM);

END;
...