Выполнение блока PL / SQL дает ошибку, которая не понятна - PullRequest
0 голосов
/ 20 января 2020

Был задан вопрос о том, чтобы написать блок PL / SQL для печати сведений о клиентах, чье общее количество заказов превышает 200, где таблица Customer имела идентификационный номер (5) первичного ключа, имя varchar2 (20), Contact_No varchar2 (10) и таблица Order имели номер Order_Id (5) первичный ключ, номер Number (4) не нулевой, номер C_id (5) ссылается на Customer (ID).

Если запись не найдена "Нет «Найденные записи» должны быть распечатаны.

Это код, который я написал:

SET SERVEROUTPUT ON;

begin
  dbms_output.put_line('Customer_Id ' || 'Customer_Name '|| 'Customer_Phone');
  for cur_d in (select o.C_ID,total AS sum(o.QUANTITY) from Orders o group by o.C_ID) loop
  from Customers c
  where c.ID = cur_d.C_ID and cur_d.total > 200;
  dbms_output.put_line(c.ID || c.Name || c.Contact_No);
  end loop;
end;
/

Я столкнулся с ошибкой -

for cur_d in (select o.C_ID,total AS sum(o.QUANTITY) from Orders o group by o.C_ID) loop 

ERROR at line 2: 
ORA-06550: line 2, column 41: 
PL/SQL: ORA-00923: FROM keyword not found where expected 
ORA-06550: line 2, column 15: 
PL/SQL: SQL Statement ignored 
ORA-06550: line 3, column 1: 
PLS-00103: Encountered the symbol "FROM" when expecting one of the following: 
( begin case declare exit for goto if loop mod null pragma 
raise return select update while with '<'an identifier'>'
'<'a double-quoted delimited-identifier'> ')

Ответы [ 3 ]

1 голос
/ 20 января 2020

Даже после того, как вы исправите существенное, которое было указано, ваша процедура все равно не будет выполнена. Вы указываете, что если запись не найдена, вы печатаете сообщение на этот счет. Это само по себе неоднозначно. Означает ли это отсутствие записей в таблице данных или отсутствие записей для данного клиента? В любом случае у вас нет кода для создания такого сообщения. Как вы ожидаете, что это будет написано. Наконец, SQL - это обработка, основанная на множествах, так что вам нужно начать думать в терминах множеств вместо циклов Следующее уменьшает доступ БД к одному запросу; l oop предназначен только для печати результатов.

begin
    dbms_output.put_line('Customer_Id ' || 'Customer_Name '|| 'Customer_Phone' || 'Total Orders');

    for cur_d in (
        with order_totals as 
             ( select c_id,  sum (quantity) order_total
                 from orders
                group by c_id
               having sum(quantity) > 200
             ) 
        select c.id, c.name, c.contact_no
             , case when o.c_id is null 
                    then 'No Records Found'
                    else to_char(o.order_total)
                end order_total
          from customers c
          left join order_totals o 
               on c.id = o.c_id  
         order by c.id
        )
    loop 
       dbms_output.put_line(cur_d.ID || cur_d.Name || cur_d.Contact_No || cur_d.order_total);
    end loop;
end; 

Результаты сведены воедино так же, как у вас изначально. Вам нужно тренировать свою презентацию.

1 голос
/ 20 января 2020

Между частями "для .. l oop" и "from" отсутствует деталь "выбрать в". Это должно быть так, чтобы работать

for ..... loop
  select some_column -- <-- this line is missing
    into some_variable -- <-- this line is missing too
    from ..........
0 голосов
/ 23 января 2020

Это проблема, при которой форматирование вашего кода сделает проблему очевидной. Если вы всегда начинаете новую строку и отступ после for xxx in (, а также ставите закрывающую скобку на своей строке и добавляете несколько пробелов между командами, вы получите это, что явно неверно:

begin
    dbms_output.put_line('Customer_Id ' || 'Customer_Name '|| 'Customer_Phone');

    for cur_d in (
        select o.c_id, total as sum(o.quantity)
        from   orders o
        group by o.c_id
    )
    loop
        from   customers c
        where  c.id = cur_d.c_id
        and    cur_d.total > 200;

        dbms_output.put_line(c.id || c.name || c.contact_no);
    end loop;
end;

Первое утверждение внутри l oop, кажется, что-то упустило, как упоминал Экочергин.

total as sum(o.quantity) в обратном порядке, как упомянул Туро.

Если вы хотите id, name и contact_no для печати в столбцах, вы должны посмотреть lpad и rpad для их форматирования. Просто объединяя их вместе, вы получите что-то нечитаемое.

dbms_output внутри l oop относится к c.id, c.name и c.contact_no, но запись называется cur_d, а не c.

Также cur_d - слегка запутанное название записи (это не курсор). Я всегда использую r для записей курсора, если нет каких-либо других r, которые могут быть перепутаны с.

...