У меня есть таблица, которую я пытаюсь заполнить с помощью сценария plsql (работает на разработчику plsql).Фактический оператор DML содержится в процедуре внутри пакета.Процедура вставляется только если запись еще не существует.
Не работает.Часть, которая проверяет существование, возвращает true после первой итерации цикла скрипта, даже если она на самом деле не существует в таблице.
Если я помещу коммит за пределы цикла, ничего не будет вставлено вообще ипроверки существования возвращают true для всех итераций, даже если таблица пуста.
Когда я пытаюсь упростить вставку с проверкой существования, чтобы она была всего в одном операторе без обработки исключений, я получаю тот же результат.
Пожалуйста, скажите мне, что я делаю здесь не так.
CREATE OR REPLACE PACKAGE BODY some_package
IS
PROCEDURE add_to_queue(id IN NUMBER)
IS
pending_record VARCHAR2(1);
BEGIN
-- this part succeeds even if nothing matches the criteria
-- during the loop in the outside script
SELECT 'Y'
INTO pending_record
FROM dual
WHERE EXISTS (SELECT 'x' FROM some_queue smq
WHERE smq.id = id AND smq.status IS NULL);
EXCEPTION
WHEN NO_DATA_FOUND THEN
INSERT INTO some_queue (seqno, id, activity_date)
VALUES (some_sequence.nextval, id, SYSDATE);
WHEN OTHERS THEN
NULL;
END;
END some_package;
CREATE TABLE some_queue
(
seqno VARCHAR2(500) NOT NULL,
id NUMBER NOT NULL,
activity_date DATE NOT NULL,
status VARCHAR2(25),
CONSTRAINT some_queue_pk PRIMARY KEY (seqno)
);
-- script to randomly fill in the table with ids from another table
declare
type ids_coll_tt is table of number index by pls_integer;
ids_coll_table ids_coll_tt;
cursor ids_coll_cur is
select tab.id
from (select *
from ids_source_table
order by dbms_random.value ) tab
where rownum < 10;
begin
open ids_coll_cur;
fetch ids_coll_cur bulk collect into ids_coll_table;
close ids_coll_cur;
for x in 1..ids_coll_table.count
loop
some_package.add_to_queue(ids_coll_table(x));
commit; -- if this is here, the first iteration gets inserted
end loop;
-- commit; -- if the commit is done here, nothing gets inserted
end;
Примечание: я перевел этот код, чтобы сделать его более общим для публикации.Извините, если есть какие-либо опечатки.
Обновление: даже если я помещаю все в сценарий и не использую пакет, я не могу должным образом проверить наличие и получаю те же результаты.