PL / SQL Данных не найдено даже там должно быть? - PullRequest
2 голосов
/ 09 июля 2020

В настоящее время я изучаю PL / SQL атм, и у меня возникла проблема с одним из моих домашних вопросов.

В приведенном ниже коде я получаю ввод данных пользователем для провинции и изолирую выберите результаты, используя указанную провинцию в объявлении курсора и пытаясь запустить процедуру visitandtotal, но все, что я получаю, - это данные, не найденные, почему?

подсказка пользователя

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;

Процедура

  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 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.

1 Ответ

1 голос
/ 13 июля 2020

Я не могу комментировать из-за меньшего количества репутации.

Ошибка NO_DATA_FOUND возникает из-за процедуры, в которой у вас есть предложение where и группировка по ..

и если нет записей с параметром "userinput" приводит к исключению.

Я бы посоветовал изменить процедуру, поскольку нам определенно не нужна группа по custname, поскольку custname является частью предложения where;

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;

Но для чего угодно Причина в том, что если вы настаиваете на сохранении предложения group by, вы должны явно обработать исключение NO_DATA_FOUND в процедуре visitandtotal

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;
...