UPDATE в PostgreSQL

Статья основана на 17 видео из 30 тем курса SQL c 0 от Аристова Евгения. Ссылки на видео на платформах RUTUBE и VK видео.

В прошлой лекции была разобрана команда INSERT для вставки данных. Помимо добавления новых строк, бывает нужно и обновление старых. Для этого существует команда UPDATE, использование которой составляет ~5% от всех операций в СУБД.

UPDATE

UPDATE [ ONLY ] table_name [ * ] [ [ AS ] alias ]
    SET { column_name = { exression | DEFAULT } |
        } [, ...]
    [ FROM from_item [, ...] ]
    [ WHERE condition ]

Внутри операции можно использовать предыдущее значение (например, увеличить его).

Важно не забывать про условие WHERE (редко нужно обновлять все данные без условия). Без WHERE можно потерять все данные, которые потом будет очень сложно или невозможно восстановить.

При обновлении данных занимаемая память увеличивается вдвое, поэтому желательно применять UPDATE к бачам данных.

Создадим таблицу Склад и добавим две записи:

DROP TABLE IF EXISTS warehouse;
CREATE TABLE warehouse (
  id serial UNIQUE,
  name text NOT NULL DEFAULT '',
  kolvo int NOT NULL DEFAULT 0,
  price numeric NOT NULL DEFAULT 0.0,
  salesTime timestamp with time zone NOT NULL DEFAULT current_timestamp, -- UTC
  salesTime2 timestamp NOT NULL DEFAULT current_timestamp
);
INSERT INTO warehouse (name,kolvo,price) VALUES
    ('apple',10,10.2),
    ('grape',20,'20.2');

С помощью команды просмотрим строчку с id равным 1:

SELECT * 
FROM warehouse 
WHERE id = 1;

Обновим эту строчку (условие WHERE) и снова выведем её:

UPDATE warehouse
    SET kolvo = kolvo + 30, 
    price = 30.3
WHERE id = 1;

SELECT * 
FROM warehouse 
WHERE id = 1;

Мы обновили значение поля kolvo с использованием предыдущего, а полю price присвоили новое значение.

WHERE в UPDATE работает точно так же, как и в SELECT. В UPDATE прописываются только те поля, которые обновляются, остальные остаются неизменны.

Также можно указывать поля через запятую:

UPDATE warehouse
    SET (kolvo,price) = (30,30.3)
WHERE id = 1;

SELECT * 
FROM warehouse 
WHERE id = 1;

Такой формат написания команды не рекомендуется, так как визуально непонятно, в какой столбец какое значение будет записано.

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

UPDATE warehouse
    SET salesTime = DEFAULT
WHERE id = 1;

SELECT * 
FROM warehouse 
WHERE id = 1;

Salestime изменился на текущее время.

Как не потерять данные

Рекомендуется в начале написания команды UPDATE ставить невыполнимое условие:

UPDATE warehouse
    SET
WHERE 1=0;

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

А после окончательного правильного написания убрать это условие.

Другой способ – писать команды внутри транзакции (подробнее о транзакциях в моей статье):

BEGIN;
UPDATE warehouse
    SET ;
ROLLBACK;

Любая операция внутри транзакции будет отменена после применения ROLLBACK.

После проверки корректности работы заменить ROLLBACK на COMMIT.

Конфликты

Для команды INSERT нет конструкции ON CONFLICT, поэтому конфликты можно обрабатывать только с помощью EXEPTION.

Пример запроса с конфликтом:

UPDATE warehouse
SET id = id + 1;

Данная команда пытается присвоить первой строчке id 2, в то время как у второй строчки остается всё ещё не изменённый id 2 (а поле id должно быть уникальным).

RETURNING

После изменения ячейки, можно узнать её новое значение с помощью RETURNING.

    [ RETURNING * | output_expression [ [ AS ] output_name ] [, ...] ]

Выведем количество и цену после их обновления:

UPDATE warehouse
    SET kolvo = kolvo + 40,
    price = 40.3
WHERE id = 1
RETURNING kolvo, price;

В отличие от INSERT, в UPDATE нельзя получить предыдущее значение через EXCLUDED:

UPDATE warehouse as w
    SET (kolvo,price) = (50,50.3)
WHERE id = 1
RETURNING EXCLUDED.kolvo;

В таком варианте вернется уже новое значение:

UPDATE warehouse AS w
SET (kolvo,price) = (kolvo+50,50.3)
WHERE id = 1
RETURNING w.kolvo;

Презентация к статье здесь.

18 из 30 тем будет скоро доступна. Если вы хотите быстрее получить доступ – присоединяйтесь к онлайн группе, ссылка доступна в описании курса.

Комментарии

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

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

10 + семнадцать =