Использование кортежей

Статья основана на пятнадцатом видео видео из 31 темы курса SQL 2.0 — PL/pgSQL в PostgreSQL от Аристова Евгения, который является логическим продолжением курса SQL c 0. Ссылки на видео на платформах RUTUBE и VK video.

В данной статье подробно разбираются кортежи, их преимущества и недостатки и когда лучше использовать ROWTYPE.

В прошлой статье мы разобрали входные и выходные параметры, объявление параметров функции и нюанс возвращения функции.

Презентация и исходники доступны по ссылке.

Кортежи

ROWTYPE в PostgreSQL позволяет работать со строками таблиц и составными типами как с едиными объектами.

DECLARE

  emp_record employees%ROWTYPE; -- Объявление переменной типа строки таблицы

Преимущества

Автоматическая адаптация к схеме:

При изменении таблицы не нужно менять код функций

ALTER TABLE employees ADD COLUMN email TEXT;

Функция продолжит работать без изменений!

Переменная emp_record автоматически включает новое поле

Удобство работы с целыми строками:

DECLARE
original_emp employees%ROWTYPE;

Модифицируем нужные поля

original_emp.name := new_name;
original_emp.id := DEFAULT;
INSERT INTO employees VALUES (original_emp.*) RETURNING id INTO new_emp_id;
RETURN new_emp_id;

Сравнение целых строк:

current_emp employees%ROWTYPE;

cached_emp employees%ROWTYPE;

Текущее состояние

SELECT * INTO current_emp FROM employees WHERE id = emp_id;

Предположим, что у нас есть кэш (например, в другой таблице)

SELECT * INTO cached_emp FROM employees_cache WHERE id = emp_id;

Сравниваем всю строку целиком

IF current_emp IS DISTINCT FROM cached_emp THEN …

Недостатки

Производительность при частичном использовании:

НЕЭФФЕКТИВНО: выбираем все поля, но используем только одно

CREATE OR REPLACE FUNCTION get_employee_name(emp_id INTEGER)
RETURNS TEXT AS $$
DECLARE
  emp employees%ROWTYPE; -- Выбираем ВСЕ поля
BEGIN
  SELECT * INTO emp FROM employees WHERE id = emp_id;
  RETURN emp.name; -- Используем только одно поле!
END;
$$ LANGUAGE plpgsql;

Отсутствие строгой типизации при изменениях:

Проблема: если удалить поле из таблицы

ALTER TABLE employees DROP COLUMN salary;

Функция сломается в RUNTIME, а не при компиляции

Ошибка: column «salary» of relation «employees» does not exist

Сложность с NULL значениями:

DECLARE
  emp employees%ROWTYPE;
BEGIN
  -- Инициализация всей строки как
  emp := NULL;

  -- Попытка доступа к полю вызовет ERROR
  -- RAISE NOTICE 'Name: %', emp.name; -- ОШИБКА!

Лучшие практики

Используйте ROWTYPE для:

  • Триггерных функций (NEW/OLD)
  • Операций со всей строкой
  • Прототипирования

Избегайте ROWTYPE для:

  • Функций, использующих 1-2 поля
  • High-performance кода
  • Часто изменяемых таблиц

Больше примеров доступно на гитхабе и в видео.

В следующей статье мы разберём перегрузку функций.


Опубликовано

в

Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

пятнадцать + семь =