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, что было бы проще. Например.
Сообщите мне, решит ли это вашу проблему;
ПЕРЕСМОТРЕННЫЙ ОТВЕТ С КОНКРЕТНЫМИ ПРОБЛЕМАМИ ИСПОЛЬЗОВАНИЯ И ИСПОЛЬЗОВАНИЯ ИНСТРУМЕНТОВ
Проблемы: названия столбца в таблице отличаются от написанного вами кода
- WHERE d.shool_number = p_school_no; - & gt; Shool_number не является существующим столбцом, вероятно, это d.school_number
- v_lesson lessons.lesson_name%type; - & gt; фактический столбец - lesson , а не lesson_name . Я могу сказать это из вашего предложения select в процедуре
- p_lesson OUT lessons.lesson_name%type, - & gt; то же, что и пункт 2
- 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 , используйте их вместо .
- Кроме того, убедитесь, что оператор select возвращает только одну строку на school_number=20201754 , иначе вы получите ошибку ORA-01422: exact fetch returns more than requested number of rows , и тогда есть другие способы ее решения. (пока ничего не скажу по этому поводу)
- Последний этап, в котором вы пытаетесь протестировать такую процедуру, как 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 запрос, то все работает:
О причине ошибки с путями её обхода уже подробно написано в ранее данном ответе.
Вызываться без каких либо параметров, она должна просто осуществлять поиск ресторана с минимальной стоимостью оборудования и выводить его. ВСЁ!
Это можно довольно просто сделать, вернув открытый курсор неявно:
Если неявный возврат результата нежелателен, или версия БД старше 12c, то тот же самый результат можно вернуть явно с одним параметром вывода (или преобразовав в функцию):
Заметка об ограничении ответственности: так как структура таблиц и данные в вопросе приведены картинками, не представляется возможным проверить на отсутствие ошибок.
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 |
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 выполняющейся по расписанию
Читайте также: