Страницы

1 августа 2012 г.

PostgreSQL. Методы проверки результатов выполнения запроса

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

       Итак, в PostgreSQL есть способы проанализировать результаты выполенения запросов на предмет наличия возвращаемых данных. Ранее, я делал что-то типа:

if not exists(select null from table where rec_id = record_id) then
 insert... ;
else
 update... ;
end if;

Этот способ бесспорно работает, но PostgreSQL предоставлет более изящные решения, например: 


Применение переменной FOUND.

select * from table where rec_id = record_id;
if NOT FOUND then
 --записей нет
 insert... ;
else
 --записи есть
 update... ;
end if;

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

select * into myrec from table where rec_id = record_id;
if NOT FOUND then
 myrec = null;
end if;
return myrec;

FOUND так же реагирует на запросы INSERT, UPDATE, DELETE, Например:

update table set
field_1 = value1
where rec_id = record_id;

if NOT FOUND then --если update не произошел
 insert into table(field_1, rec_id)
 values (value1, record_id);
end if;

Проверка наличия записей с помощью переменной типа RECORD.

(базовый пример взят отсюда)

DECLARE
 users_rec RECORD;
BEGIN
 users_rec = null;
 ...
 SELECT INTO users_rec * FROM users WHERE user_id=us_id;

 IF users_rec IS NULL THEN
  RAISE EXCEPTION 'user_id % not found', us_id;
 END IF;
 ...
END

Если запрос должен вернуть только одну запись???

В таком случае посмотрим на следующий пример:
(пример взят отсюда)

BEGIN
 SELECT * INTO STRICT myrec FROM emp WHERE empname = myname;
EXCEPTION
 WHEN NO_DATA_FOUND THEN
  RAISE EXCEPTION 'employee % not found', myname;
 WHEN TOO_MANY_ROWS THEN
  RAISE EXCEPTION 'employee % not unique', myname;
END;

, где

STRICT - утанавливает ограничение одной записи в результате выборки запроса. Если результат меньше или больше одной записи то генерируется исключение.
NO_DATA_FOUND - тип исключения, возникающего в случае, если запрос не вернул ниодной записи.
TOO_MANY_ROWS - тип исключения, возникающего в случае, если запрос вернул более одной записи.

       Это все, что мне приглянулось на текущий момент. Уверен, что это далеко не все методы проверки результатов запроса, если кто-то знает методы которые являются более интересными, буду рад если поделитесь.

Спасибо за внимание.

4 комментария:

  1. Еще один интересный метод при выполнении апдейта и инсерта это то, что можно сделать так:
    update table set column1 = 'a' where cr_date between date1 and date2 returning id

    В таком случае апдейт возвратит сет значений полей которые мы указали и можно проконтролировать какие поля мы проапдейтили и какие значения в этих записях сейчас присутствуют.

    Для меня это было по настоящему большим открытием, так как предоставило новый инструмент для проверки измененных данных. Например, по такому сету из идентификаторов, можно легко организовать цикл.

    ОтветитьУдалить
    Ответы
    1. Да. я где-то встречал такой вариант, но он был благополучно забыт. Спасибо :)

      Удалить
  2. Ответы
    1. Вероятно 7-я версия старовата для таких инструкций :)

      Удалить