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;