Причина получения ORA-01422: точная выборка возвращает больше запрошенного количества строк
Поэтому я работаю над установщиком, где установщик подключается к базе данных, создает таблицы и заполняет их. Каждый аспект этого работает правильно, за исключением случаев, когда я пытаюсь добавить строки в таблицу certian.
declare
retVal INTEGER;
rptID INTEGER;
catID INTEGER;
wsID INTEGER;
paramID INTEGER;
dtID INTEGER;
begin
select PK into catID from RPT_CATEGORY where KEYVALUE = 'ProductivityReportsCategory';
select PK into rptID from RPT_REPORT where KEYVALUE = 'ProductivitySummaryReport2';
select PK into wsID from RPT_WEBSVC where KEYVALUE = 'NotApplicable' and category_fk = catID;
Операторы выбора, которые заполняют базу данных, выглядят так:
select PK into wsID from RPT_WEBSVC where KEYVALUE = 'GetMachineNameList' and category_fk = catID;
paramID := RPT_CONFIGURATION.ADD_PARAMETER( rptID, wsID, dtID, 'Machine', 'parameters.GetProductivityDataSet3.inserterid', 4, NULL, NULL, NULL, 0, 0, 0, 'Y', 'Y', 'N', 'N', 'Y' );
Есть еще 13 операторов выбора, структурированных подобным образом (я не буду добавлять их, так как они все похожи, и единственное отличие - это сохраненные значения, которые будут помещены в таблицу.)
Моя проблема в том, что когда я запускаю установщик, я получаю эту ошибку в журналах после завершения:
ORA-01422: exact fetch returns more than requested number of rows
ORA-06512: at line 30
Я хотел бы знать, что именно является причиной этой ошибки, и что будет средством для исправления этой ошибки?
Я провел небольшое исследование по этой теме и обнаружил, что это общая тема моего поиска:
1. В коде есть ошибка, и разработчик не осознал, что можно получить более одной возвращенной строки;
2. Данные были взломаны, а не с помощью API, так что проверка была нарушена;
3.Программа в порядке, то, что сделал пользователь, было в порядке, но два параллельных обновления произошли в одно и то же время, и ни один из них не смог увидеть незафиксированное изменение, которое сделал другой - следовательно, не подтвержден правильно.
Я уверен, что это не № 2, но я не совсем понимаю, что именно означают две другие причины, или как их исправить.
Любая помощь или предложения с благодарностью.
Спасибо
3 ответа
ORA-01422: точная выборка возвращает больше запрошенного количества строк
Это исключение возникает всякий раз, когда выполняется инструкция SELECT INTO, и находит более одной строки. Оператор SELECT INTO ожидает найти ровно одну строку, не более или менее - в противном случае возникает исключение.
В вашем примере:
select PK into wsID from RPT_WEBSVC
where KEYVALUE = 'GetMachineNameList'
and category_fk = catID;
похоже, что для каждой комбинации (KEYVALUE, CATEGORY_FK) должна быть только одна строка, но на самом деле это не так. Если должен быть только один, тогда таблица должна иметь уникальное ограничение на эти столбцы:
alter table RPT_WEBSVC add constraint RPT_WEBSVC_UK
unique (KEYVALUE, CATEGORY_FK);
Это не позволит кому-либо (или некоторому процессу) снова добавить ту же строку. Конечно, вам нужно будет де-дублировать таблицу, прежде чем вы сможете добавить это ограничение.
Это означает, что инструкция "SELECT INTO" вернула более одной строки. Этот оператор требует, чтобы запрос возвращал только одну строку. В противном случае вы должны использовать курсорный цикл для обработки строк.
Проверьте ваши операторы выбора в SQL*Plus, чтобы увидеть, какой из них является оскорбительным запросом.
Я бы посмотрел на номер 1 как на причину проблемы здесь... не видя всех операторов, трудно сказать, какой из этих запросов может вернуть более одной строки, но это хорошее место для начала, так как схемы базы данных могут измениться....