Skip to content
Advertisement

PL/SQL No data found even there should be?

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;
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement