问题
I've created a procedure that takes pid as parameter and returns monthly sale stats of that pid , it uses two tables, products and purchases where pid in purchases is foreign key referencing pid in products. The procedure builds without errors and executes well for only single row returns and otherwise give too_many_rows exception My procedure is as follows:
set serveroutput on
create or replace procedure try(
p_pid in purchases.pid%type) is
p_pname products.pname%type;
p_date varchar2(10);
p_qty_monthly number(5);
p_amnt_monthly number(7,2);
p_avg_price number(7,2);
begin
select pname, p_time, qty_month, amount_month,(amount_month/qty_month) as avg_sale into p_pname,p_date,p_qty_monthly, p_amnt_monthly, p_avg_price
FROM
(select p.pname, to_char(q.ptime,'MON yyyy') p_time,
sum(qty) as qty_month, sum(total_price) as amount_month
from products p, purchases q
where p.pid=q.pid
and q.pid= p_pid
group by pname, to_char(q.ptime,'MON yyyy'));
dbms_output.put_line ('Product name is:'|| p_pname || 'Purchase date is:' || p_date || 'Units sold per month are/is: ' || p_qty_monthly || 'Monthly sale amount: ' || p_amnt_monthly || 'Average sale price is: ' || p_avg_price);
end;
/
show errors
It's returning more than one rows for some inputs, how can I make it print all the rows rather than give too_many_rows exception?
回答1:
ORA-01403: no data found
You are getting NO DATA FOUND at run time. There is nothing wrong with your procedure code, but when you execute it, the SELECT..INTO query fails to fetch rows for the filter predicate specified.
where p.pid=q.pid
There are no rows in your table for pid='p001'
If you are sure about the error, then you could add no_data_found
EXCEPTION and catch the error.
EXCEPTION
WHEN NO_DATA_FOUND THEN
<do something>
回答2:
If you don't have any purchases in that month your query won't return any data, so the error you are receiving is a result of that. Each query needs to return a result or you get the error ORA-1403 No data found.
In your case you should use a left join so you always get a record back from purchases also when there are no records in that table to join with. So your sum will be zero in that case.
回答3:
no data found means your select query not returning any values for 'p001' p_id. And also make sure your select query should return only one row at a time otherwise it will throw an error. Because a variable will holds only one value at a time.
create or replace procedure m_pro(
p_pid in products.pid%type) is
p_pname products.pname%type;
p_date purchases.ptime%type;
p_qty_monthly purchases.qty%type;
p_amnt_monthly purchases.total_price%type;
p_avg_price purchases.total_price%type;
begin
select pname, p_time, qty_month, amount_month,(amount_month/qty_month) as avg_sale into p_pname,p_date,p_qty_monthly, p_amnt_monthly, p_avg_price
FROM
(select p.pname, to_char(q.ptime,'MON yyyy') p_time,
sum(qty) as qty_month, sum(total_price) as amount_month
from products p, purchases q
where p.pid=q.pid
group by pname, to_char(q.ptime,'MON yyyy'))
where pname=p_pname;
dbms_output.put_line ('Product name is:'|| p_pname || 'Purchase date is:' || p_date || 'Units sold per month are/is: ' || p_qty_monthly || 'Monthly sale amount: ' || p_amnt_monthly || 'Average sale price is: ' || p_avg_price);
EXCEPTION
WHEN no_data_found THEN
dbms_output.Put_line ('No values returned');
end;
/
Just add exception block before end statement.
Edit: Your select query with p_pid check is
select pname, p_time, qty_month, amount_month,(amount_month/qty_month) as avg_sale
FROM
(select p.pname, to_char(q.ptime,'MON yyyy') p_time,
sum(qty) as qty_month, sum(total_price) as amount_month
from products p, purchases q
where p.pid=q.pid and p.pid=(some value) -- in procedure p.pid=p_pid
group by pname, to_char(q.ptime,'MON yyyy'))
-- where pname=p_pname remove where pname=p_name
回答4:
In my opinion you should use Ref cursor to avoid any kind of worry for handling No Data Found Or Too many Rows Exception. Below snippet will helo you.
CREATE OR REPLACE PROCEDURE m_pro(
p_pid IN products.pid%type,
p_lst OUT sys_refcursor) -- Use ref cursor to avoid no data found or too many rows exception
IS
-- p_pname products.pname%type;
-- p_date purchases.ptime%type;
-- p_qty_monthly purchases.qty%type;
-- p_amnt_monthly purchases.total_price%type;
-- p_avg_price purchases.total_price%type;
BEGIN
OPEN p_lst FOR
SELECT pname,
p_time,
qty_month,
amount_month,
(amount_month/qty_month)
AS
avg_sale FROM
(SELECT p.pname,
TO_CHAR(q.ptime,'MON yyyy') p_time,
SUM(qty) AS qty_month,
SUM(total_price) AS amount_month
FROM products p,
purchases q
WHERE p.pid=q.pid
GROUP BY pname,
TO_CHAR(q.ptime,'MON yyyy')
) WHERE P.pid=p_pid;
END;
来源:https://stackoverflow.com/questions/33952619/sql-procedure-returning-too-many-rows