Если new.chart_number
равно NULL
, то
SELECT count(*)
FROM patients p
WHERE p.chart_number = new.chart_number
всегда возвращает 0
, поскольку в patients
не может быть строк с chart_number
, равным NULL
, поскольку столбец определен NOT NULL
, не говоря уже о том, что =
не будет работать на NULL
, но нуждается в операции IS NULL
.
Это означает, что условие
0 = (SELECT count(*)
FROM patients p
WHERE p.chart_number = new.chart_number)
всегда true
в таких случаях, что, в свою очередь, означает, что вы немедленно выходите из l oop в начале его первой итерации, но до того, как new.chart_number
даже будет изменен один раз. Остается NULL
. И поскольку он не должен быть NULL
, возникает ошибка.
Я думаю, вам просто нужно изменить порядок операторов в теле l oop. Сначала установите new.chart_number
в соответствии с последовательностью, затем проверьте, не существует ли она. Говоря о существовании, вы также можете использовать EXISTS
здесь и только оператор присваивания вместо SELECT ... INTO
.
...
IF new.chart_number IS NULL
OR new.chart_number = 0 THEN
LOOP
new.chart_number := nextval('chartsequence');
EXIT WHEN NOT EXISTS (SELECT *
FROM patients p
WHERE p.chart_number = new.chart_number);
END LOOP;
END IF;
...