Statement ignored oracle ошибка

Обновлено: 03.07.2024

Я новичок в PL / SQL и пытаюсь написать процедуру. Будет запрошена процедура с номером школы и курсом, midterm_not, final_not, будет показано среднее значение, но промежуточные и итоговые оценки будут рассчитаны в%. Если ему меньше 60, он будет окончен и будет принят.

Я сделал что-то подобное, когда запустил процедуру, в ней написано "Procedure student_grade compiled" , но когда я пытаюсь запустить часть DECLARE , она выдает такую ​​ошибку:

Проблема в p_average: = Может ли кто-нибудь помочь мне с этими проблемами?

Всего 2 ответа

Вы почти все сделали нормально. Немного о процедуре,

Выполните команду ниже (возможно, вы не заметили ошибку)

вам не нужно делать параметр p_average как IN OUT, OUT должно быть достаточно, если вы рассчитываете его внутри.

, чтобы присвоить какое-либо значение параметру OUT, вам не нужно использовать SET. Допускается только присваивание с использованием оператора присваивания. см. ниже

Я считаю, что из-за ошибки в процедуре, которую вы не смогли протестировать, после внесения вышеуказанных изменений она должна работать.

Вы также можете протестировать его с помощью анонимного блока PL / SQL вместо окна команд SQL, что было бы проще. Например.

Сообщите мне, решит ли это вашу проблему;

ПЕРЕСМОТРЕННЫЙ ОТВЕТ С КОНКРЕТНЫМИ ПРОБЛЕМАМИ ИСПОЛЬЗОВАНИЯ И ИСПОЛЬЗОВАНИЯ ИНСТРУМЕНТОВ

Проблемы: названия столбца в таблице отличаются от написанного вами кода

  1. WHERE d.shool_number = p_school_no; - & gt; Shool_number не является существующим столбцом, вероятно, это d.school_number
  2. v_lesson lessons.lesson_name%type; - & gt; фактический столбец - lesson , а не lesson_name . Я могу сказать это из вашего предложения select в процедуре
  3. p_lesson OUT lessons.lesson_name%type, - & gt; то же, что и пункт 2
  4. p_average := (((d.midterm_notu_1 * 25)/100) + ((d.midterm_notu_2 * 30)/100) + ((d.final_notu * 45)/100)); - вы не можете ссылаться на столбцы таким образом, что это означает с "d." , когда код не знает, на что он ссылается. d , который вы использовали в запросе выбора в качестве псевдонима для таблицы lessons , и с помощью оператора select заканчивается область действия d на этом заканчивается. Поскольку вы уже перенесли значения в выходные переменные, такие как p_midterm_1, p_midterm_2, p_final , используйте их вместо .
  5. Кроме того, убедитесь, что оператор select возвращает только одну строку на school_number=20201754 , иначе вы получите ошибку ORA-01422: exact fetch returns more than requested number of rows , и тогда есть другие способы ее решения. (пока ничего не скажу по этому поводу)
  6. Последний этап, в котором вы пытаетесь протестировать такую ​​процедуру, как student_grade( v_lesson, v_midterm_1, v_midterm_2 , v_final, v_average ); - & gt; вы передаете в процедуру неправильное количество аргументов, не включая v_school_no в качестве первого параметра.

Однако я создал свою собственную настройку и соответственно изменил процедуру и тест, см. ниже.

Кроме того, «set» (SET p_average: =) недопустим для SELECT. Он принадлежит UPDATE.

Несмотря на многочисленные предупреждения, многие админи пользователи продолжают настаивать на том, что им кровь из носу нужны красивые картинки и возможность потренироваться в непопадании мышью куда надо в противовес нормальной работе БД. Да-да, вы не ошиблись, это еще одно ведро помоев на поделие индусов, которые некоторые называют Enterprise manager, хотя на деле оно называется куда более прозаично - dbconsole. Утечки памяти (прелестно получить рано утром базу в свопе), "забытые" XML-файлики в транспорте на 16Гб - это первое, что мне приходит в голову, когда произносится слово dbconsole. Ну и в качестве побочного эффекта - падение dbconsole ровно в тот момент, когда вам очень и срочно нужно что-то в базе сделать, а кроме как мышкой махать в вебе вы ничего не умеете. Без обид, сам наступал на все вышеперечисленные грабли, потому и рекомендую никогда dbconsole не ставить (это про 10 и 11 версии Oracle, что будет в 12 пока сказать не могу), а если поставили - снести как можно быстрее. Спорить и уговаривать не буду, это мое мнение и верить ему или нет - решать вам.

Второй, сопутствующий вид грабель - Oracle Workspace manager.
Самый простой способ убедиться в его наличии в своей системе -

если он что-то выдает, то поздравляю, вы попали.
Прикол в том, что даже если его там нет, но он был, то это может быть еще менее приятно, но проводить сейчас полные исследования мы не будем, можно еще в dba_registry заглянуть, оттуда его разрегистрировать иногда забывают. На самом деле зря я начал рисовать все в таких тонах. Если пакет есть, корректно работает и его никто не трогает, то все хорошо работает. Хуже становится, когда эта пакость начинает сбоить. Ввиду того, что завязана она глубоко в системе, включая триггеры на DDL, гору ORA-600 при обычной alter table move получить - как нечего делать. Именно на такое я сейчас и наступил. Были инвалиды в WMSYS, юзера тупо дропнули, в общем мутная история и куча ORA-600 при работе оптимизатора. И при попытке вытащить базу через expdp

если бы ошибка была единственной, то в принципе можно было бы ее игнорировать - дамп бы получился корректный, но . в общем, пришлось разбираться. Вот тут я и порадовался триггерам на DDL в трейсе. Выкинул - ожило. Потом OWM поставил обратно, всем таблицам несколько раз сделал

(это ошибка expdp выше указывает на косяк с версионностью), убедился, что

Разбирая новые возможности Oracle 12c, то тут, то там сталкиваюсь с подводными камнями, когда не всё работает так, как ожидалось, падает или просто не очевидно. Конечно, это стандартная ситуация когда в первом релизе новой версии много сырого… но, как известно, предупреждён — значит вооружен. Вероятно, кому-то пригодится, чтобы не повторять мои грабли.

Пишу грабли в порядке наступления на них.

PS: edited: добавил в конце баг о котором забыл написать сразу (использование в PL/SQL, SQL-конструкций в WITH которых испоьзован PL/SQL).

Знакомим PMON с локальным listener

Начнём с простого, что даже не совсем бага, а вопрос конфигурирования.
Инсталлировали в стандартной установке и настройке Oracle 12c (в моём случае — на Oracle Linux, но, думаю, не критично).
— Создаём CDB базу.
— Поключаем/создаём PDB-базы.
По-умолчанию добавленные базы не видится listener-ом. «Из коробки» PMON не подружился с listener-ом, живущим на том же сервере и автоматическая регистрация не происходит. Не трагедия, однако руками добавлять записи в listener.ora, как-то совсем не интересно в контексте новой фичи multitenant architecture.
Давайте познакомим PMON и локально живущий listener:

База зарегистрировалась, listener увидел, радость наступила. Нельзя сказать что это особенность именно 12-ки, но именно в ней появилась возможность буквально на ходу добавлять / управлять базами, и в рамках Multitenant architecture автоматическая регистрация баз в listener, как никогда актуальна. Раньше создание новой базы было намного большим «событием» и добавить пару строк в listener.ora не вызывало у меня каких-либо предубеждений.

Автозапуск PDB после перезагрузки

Перезапускаем сервер. CDB поднялась. PDB — не открыты (при подключении ошибка database shutdown or startup in progress).
Не знаю, может это и правильно, что после перезагрузки сервера администратор должен подключиться к CDB базе и сказать

Вроде как просто так базы не перезагружаются (не должны)… Но что-то мне подсказывает, что это, мягко говоря, не удобно. А DBA, которые поддерживают десятки и сотни баз одновременно — явно спасибо не скажут.
Настройки или команды которая бы убедила Оракл что автостартовать PDB-шки всё таки нужно, не обнаружилось (может плохо искал. Подскажите в коммантариях если кто нашёл).
Во всезнающем интернете этот момент уже давно не новость и наиболее распространённая рекомендация:


По личным убеждениям я не очень люблю триггеры, но в данном случае, это, похоже, самое малое из доступных зол.

Invisible columns

Особенность не Оракла, а PL/SQL developer-а (версия10.0.1.1694 — скачан с сайта PL/SQL Developer-а буквально недавно), но всё же.
Сравним поведение на невидимой колонке sqlplus (ведёт в соответсвии с документацией):


И PL/QSL Developer command window:

Не знает пока что Pl/Sql developer про новую фичу, что не удивительно. Но не все осознают что command window у PL/SQL-девелопера — это не честный sql*plus через какой-нибудь pipe, а просто псевдо-подобный интерфейс.
Думаю скоро образумятся, но в первый момент несколько удивился и задумался.

PL/SQL support in with

Как утверждает Оракл, эта фича была сделана в первую очередь для поднятия производительности (детальное рассмотрение фичи оставим за скобками, ибо оффтопик к теме поста), как и умолчим, что pragma UDF работает в этих целях не хуже, но…
«НО» заключается в баге обнаруженном Johnathan Lewis и описанном в его блоге.
Добавиви одну performance «фичу» поламали (в некоторых случаях) — другую — DETERMINISTIC.

Рассмотрим на примере кода:

Хотя, справедливости ради, проявляется это не во всех случаях:

SQL Text expansion

Ещё одно приятное нововведение — новая процедура DBMS_UTILITY.EXPAND_SQL_TEXT — я её уже описывал раньше на хабре.
Когда её испытывал, она замечательно отработала как на моих view и таблицах с VPD…, так и к примеру, на all_users… однако попытка применить её к all_objects привела к ошибке в пакете dbms_utility. Предполагаю, причина в том, что даже у пользователя с ролью DBA не обнаружилось доступа к каким-то совсем внутренним системным объектам… а может просто баг в коде.

И вот ещё пара вещей, с которыми столкнулся не сам, но тоже было интересно почитать у других:

DBMS_METADATA and session sequence
Pagination, массивы и run-time расчёт количества строк для fetch

Нашёл у человека в блоге

PPS: добавлено позже (вспомнил ещё)

PL/SQL support in SQL with in PL/SQL

Название — масло масляное. Давайте разберёмся.
Похоже, PL/SQL пока не в курсе о расширении SQL-языка, и пока не поддерживает таких SQL конструкций:

Колонки

Мне необходимо написать процедуру поиска ресторана с минимальной стоимостью оборудования.

Я написал следующее:

Но получаю ошибку:

Может кто-то подскажет, в чем у меня ошибка?

Причем, если я пишу просто SQL запрос, то все работает:

Просто запрос


50.3k 152 152 золотых знака 54 54 серебряных знака 211 211 бронзовых знаков

О причине ошибки с путями её обхода уже подробно написано в ранее данном ответе.

Вызываться без каких либо параметров, она должна просто осуществлять поиск ресторана с минимальной стоимостью оборудования и выводить его. ВСЁ!

Это можно довольно просто сделать, вернув открытый курсор неявно:

Если неявный возврат результата нежелателен, или версия БД старше 12c, то тот же самый результат можно вернуть явно с одним параметром вывода (или преобразовав в функцию):

Заметка об ограничении ответственности: так как структура таблиц и данные в вопросе приведены картинками, не представляется возможным проверить на отсутствие ошибок.


50.3k 152 152 золотых знака 54 54 серебряных знака 211 211 бронзовых знаков

SELECT INTO это отдельный вид запроса. INTO нельзя использовать в подзапросе, можно только в запросе верхнего уровня. Поэтому и возникает ошибка.

Впрочем, это не единственная проблема в процедуре:

Вообще непонятно зачем выбирать minprice в переменную. Переменная нигде не используется в дальнейшем. Проще написать подзапрос также как в SQL.

Запрос SELECT посреди процедуры сам по себе ничего не делает. :

a. Если нужно вернуть данные по ресторану в отдельных переменных, то нужно объявить аргументы процедуры ( p_rid , p_rname и т.д.), записывать данные в них с помощью SELECT INTO .

б. Если нужно вернуть список минимальных ресторанов, то почитайте как вернуть из процедуры курсор в Oracle.

в. Если нужно распечатать данные о ресторане(-ах), то почитайте как пользоваться пакетом dbms_output . В любом случае потребуется использовать один из способов а) или б).

Из комментариев: Вызываться без каких либо параметров, она должна просто осуществлять поиск ресторана с минимальной стоимостью оборудования и выводить его. ВСЁ. (ノಠ益ಠ)ノ彡┻━┻

«Выводить» я понял, как выводить в выходной поток БД. Вполне может быть что имеется ввиду что-то другое, например то, что у процедуры будут OUT параметры, через которые будут возвращены данные.

Для отключения данного рекламного блока вам необходимо зарегистрироваться или войти с учетной записью социальной сети.

Конфигурация компьютера
Процессор: Intel Celeron M520 1.60GHz
Память: SODIMM 5300 512+1024MB
HDD: Seagate 120GB 5400R SATA
Видеокарта: Intel GMA 950
CD/DVD: MATSHITADVD-RAM UJ-850S, ATAPI CD/DVD-ROM drive
Монитор: WXGA 14.1'' 1280x800
ОС: FreeBSD 6.3-x64, Enterprise Linux 5

Что-то не сильно помагает, у меня и так книга от авторов, работающих в оракл.

Взял один из примеров, приведённых по ссылке:

Конфигурация компьютера
Процессор: Intel Celeron M520 1.60GHz
Память: SODIMM 5300 512+1024MB
HDD: Seagate 120GB 5400R SATA
Видеокарта: Intel GMA 950
CD/DVD: MATSHITADVD-RAM UJ-850S, ATAPI CD/DVD-ROM drive
Монитор: WXGA 14.1'' 1280x800
ОС: FreeBSD 6.3-x64, Enterprise Linux 5
Странные какие-то глюки были, всё заработало, проблема была в неправильном символе перехода на новую строку (я текст в gedit'е набирал), если набирать непосредственно в окошке веб-интерфейса или в каком-нибудь другом редакторе, то всё работает нормально.
ADD_JOB(id JOBS.JOB_ID%type,title JOBS.JOB_TITLE%type) as »

укажи типы явно.

declare begin ADD_JOB('IT_DBA','Database Administrator'); ADD_JOB('ST_MAN','Stock Manager'); end; »

execute ADD_JOB('IT_DBA','Database Administrator');
execute ADD_JOB('ST_MAN','Stock Manager');

а вот так не пробЫвал?

PS: не называй идентификаторы типа job или jobs!
потомучто в оракле job - это специальный объект. т.е. блок pl/sql выполняющейся по расписанию

Читайте также: