ORA-00928: отсутствует ключевое слово SELECT

В MYTABLE есть курсы и курсы их предшественника. Я пытаюсь найти курсы, которые необходимо пройти после указанного курса. Я получаю сообщение об ошибке SELECT. Почему я получаю эту ошибку, хотя у меня есть оператор SELECT в операторе FOR? Где я делаю не так?

DECLARE
  coursename varchar2(200) := 'COURSE_101';
  str        varchar2(200);
BEGIN
  WITH DATA AS
    (select (select course_name 
             from MYTABLE 
             WHERE predecessors like ('''%' || coursename||'%''') 
            ) str
     from dual
    )
    FOR cursor1 IN (SELECT str FROM DATA) 
    LOOP
      DBMS_OUTPUT.PUT_LINE(cursor1);
    END LOOP;
end;

3 ответа

Решение

Если я не ошибаюсь, предложение WITH factoring не может быть использовано таким образом; вам придется использовать его как встроенное представление, например:

declare
  coursename varchar2(200) := 'COURSE_101';
  str        varchar2(200);
begin
  for cursor1 in (select str 
                  from (select (select course_name 
                                from mytable 
                                where predecessors like '''%' || coursename||'%'''
                               )  str
                        from dual
                       )
                 ) 
  loop
    dbms_output.put_line(cursor1.str);
  end loop;
end;
/

Помимо того, что он не работает (неправильное условие LIKE), вы слишком усложнили его. Вот как это на самом деле делает что-то:

SQL> create table mytable(course_name  varchar2(20),
  2                       predecessors varchar2(20));

Table created.

SQL> insert into mytable values ('COURSE_101', 'COURSE_101');

1 row created.

SQL>
SQL> declare
  2    coursename varchar2(20) := 'COURSE_101';
  3  begin
  4    for cursor1 in (select course_name str
  5                    from mytable
  6                    where predecessors like '%' || coursename || '%'
  7                   )
  8    loop
  9      dbms_output.put_line(cursor1.str);
 10    end loop;
 11  end;
 12  /
COURSE_101

PL/SQL procedure successfully completed.

SQL>

Кроме того, это предложение WHERE правильно? ПРЕДСЕДАТЕЛЯМ НРАВИТСЯ КУРС? Я не говорю, что это неправильно, просто выглядит несколько странно.

Чтобы немного расширить ответ @Littlefoot: вы можете использовать общее табличное выражение (предложение WITH) в вашем курсоре, но WITH должно быть частью оператора SELECT курсора, а не отдельно от него:

DECLARE
  coursename varchar2(200) := 'COURSE_101';
BEGIN
  FOR aRow IN (WITH DATA AS (select course_name AS str
                               from MYTABLE 
                               WHERE predecessors like '''%' || coursename||'%''')
               SELECT str FROM DATA)
  LOOP
    DBMS_OUTPUT.PUT_LINE(aRow.str);
  END LOOP;
END;

Также обратите внимание, что итерационная переменная в цикле курсора FOR представляет строку, возвращаемую оператором SELECT курсора, поэтому, если вы хотите отобразить то, что было возвращено курсором, вы должны использовать нотацию с точечной переменной (например, aRow.str) извлечь поля из строки.

Удачи.

CREATE TABLE product(PRODUCT_ID int Первичный ключ, NAME VARCHAR (20) не нуль, Batchno int не null, Rate int не null, Tax int не null, Дата истечения срока действия не null );

ВСТАВЬТЕ В ЦЕННОСТИ ПРОДУКТА (1, 'vasocare', 32, 15, 2, 01-ЯНВ-2021);

Другие вопросы по тегам