I’m currently learning PL/SQL atm and I have run into an issue with one of my homework questions.
In the below code, I’m getting user input for a province and isolating select results using said province in the declaration of the cursor and trying to run the visitsandtotal procedure but all I’m getting is no data found, why?
user prompt
SET SERVEROUTPUT ON
ACCEPT prov PROMPT 'Enter Province: ';
DECLARE
customerprov VARCHAR2(4000);
customername VARCHAR2(4000);
visits NUMBER;
total FLOAT;
CURSOR prov_cursor is
Select custprovince, custname
into customerprov, customername
from si.customer
where upper(custprovince) = '&prov';
BEGIN
for c in prov_cursor loop
visitsandtotal(c.custname, visits, total);
dbms_output.put_line('Name: ' || c.custname || ' Visits: ' || visits || ' Total Labor Cost: ' || total);
end loop;
END;
Procedure
CREATE OR REPLACE PROCEDURE visitsandtotal (
userinput IN VARCHAR2
, visits OUT NUMBER
, total OUT FLOAT
) IS
BEGIN
SELECT
COUNT(*) AS visits
, SUM(s.laborcost) AS totalcost
INTO
visits
, total
FROM
si.customer c
INNER JOIN si.servinv s ON c.custname = s.custname
WHERE
s.custname = userinput
GROUP BY
c.custname
, s.custname ;
END;
Error
Error report -
ORA-01403: no data found
ORA-06512: at "S6_TRAN84.VISITSANDTOTAL", line 7
ORA-06512: at line 11
01403. 00000 - "no data found"
*Cause: No data was found from the objects.
*Action: There was no data from the objects which may be due to end of fetch.
Advertisement
Answer
I cannot comment due to less number of reputation.
NO_DATA_FOUND error comes from the procedure where you have where clause and group by..
and if no records with parameter “userinput” leads to the exception.
I would suggest to change the procedure as we certainly don’t need the group by custname as the custname is part of where clause;
CREATE OR REPLACE PROCEDURE visitsandtotal
(
userinput IN VARCHAR2
,visits OUT NUMBER
,total OUT FLOAT
)
IS
BEGIN
SELECT COUNT(*) AS visits
,SUM(s.laborcost) AS totalcost
INTO visits
,total
FROM si.customer c
INNER JOIN si.servinv s
ON c.custname = s.custname
WHERE s.custname = userinput;
--removed group by as custname is part of where clause
END visitsandtotal;
But for whatever reason if you insists to keep the group by clause, you have to handle NO_DATA_FOUND exception explicitly in the procedure visitsandtotal
CREATE OR REPLACE PROCEDURE visitsandtotal
(
userinput IN VARCHAR2
,visits OUT NUMBER
,total OUT FLOAT
)
IS
BEGIN
SELECT COUNT(*) AS visits
,SUM(s.laborcost) AS totalcost
INTO visits
,total
FROM si.customer c
INNER JOIN si.servinv s
ON c.custname = s.custname
WHERE s.custname = userinput;
GROUP BY c.custname,s.custname;
-- you dont need to mention custname from both table as join is in place
EXCEPTION
WHEN no_data_found THEN
--HERE - write your exception code whatever you like to add
END visitsandtotal;