PostgreSQL: как вставлять, обновлять и удалять данные
За 15–20 минут вы создадите таблицу контактов в PostgreSQL 16, добавите записи, измените одну из них и безопасно удалите строку. Каждый шаг заканчивается проверкой результата.

За 15–20 минут вы создадите таблицу контактов в PostgreSQL 16, добавите записи, измените одну из них и безопасно удалите строку. Инструкция рассчитана на работу через psql: после каждого SQL-запроса вы увидите, что именно изменилось.
Что нужно до начала
Подготовьте установленный PostgreSQL 16 и доступ к базе данных. Подойдёт локальная база, тестовый стенд или отдельная схема проекта. Команды ниже выполняются в psql или в SQL-консоли вашей среды разработки.
- пользователь PostgreSQL с правом создавать таблицы в выбранной базе;
- название базы данных и пароль, если сервер требует аутентификацию;
- чистая тестовая схема: первый шаг удаляет таблицу с таким именем;
- клиент
psqlверсии 16 или совместимый SQL-редактор.
Не запускайте блок с DROP TABLE в рабочей базе: он удалит таблицу и все её строки. В примере используется PostgreSQL 16; показанный синтаксис также относится к базовым операциям PostgreSQL 15 и 17, но перед переносом в проект проверьте документацию вашей версии.
Какой запрос за что отвечает
| Задача | Команда | Что проверить |
|---|---|---|
| Добавить строки | INSERT | Количество вставленных строк и результат RETURNING |
| Изменить строки | UPDATE | Условие WHERE и число обновлённых строк |
| Удалить строки | DELETE | Условие WHERE и повторный SELECT |
Термин. Транзакция — группа SQL-операций, которую база применяет целиком или не применяет вообще. Она позволяет проверить результат и отменить изменение до команды COMMIT.
Самая дорогая ошибка в CRUD-запросах — не неправильное значение, а отсутствующее или слишком широкое условие
WHERE.
Пошаговая инструкция
Шаг 1. Создайте тестовую таблицу
Сначала создайте минимальную таблицу контактов. Поле id получит уникальный идентификатор автоматически, а email не может быть пустым и повторяться.
DROP TABLE IF EXISTS contacts;
CREATE TABLE contacts (
id integer GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
name text NOT NULL,
email text NOT NULL UNIQUE,
phone text,
created_at timestamptz NOT NULL DEFAULT now()
);
SELECT column_name, data_type
FROM information_schema.columns
WHERE table_name = 'contacts'
ORDER BY ordinal_position;Проверка: запрос вернёт пять столбцов, включая id, name, email, phone и created_at. Сообщение CREATE TABLE означает, что таблица создана.
Шаг 2. Вставьте одну запись
Для добавления строки используйте INSERT INTO. Перечисляйте столбцы явно: если структура таблицы изменится, запрос не начнёт случайно записывать значения в неправильном порядке.
INSERT INTO contacts (name, email, phone)
VALUES ('Анна Петрова', 'anna@example.com', '+79990000001')
RETURNING id, name, email, phone, created_at;Проверка: RETURNING покажет созданную строку и её новый id. В psql также появится сообщение INSERT 0 1.
Шаг 3. Вставьте несколько записей одним запросом
Если значения уже известны, несколько строк можно добавить одним INSERT. Это короче серии одиночных запросов и позволяет получить результат одной выборкой.
INSERT INTO contacts (name, email, phone)
VALUES
('Илья Смирнов', 'ilya@example.com', '+79990000002'),
('Мария Орлова', 'maria@example.com', NULL)
RETURNING id, name, email;Проверка: должны вернуться две строки, а в консоли — INSERT 0 2. Поле phone у Марии будет иметь значение NULL, потому что оно не объявлено обязательным.
Шаг 4. Обновите конкретную запись
Перед изменением найдите строку по уникальному идентификатору. В рабочем приложении это значение обычно приходит из запроса пользователя или из предыдущего результата INSERT.
SELECT id, name, email, phone
FROM contacts
WHERE email = 'maria@example.com';Скопируйте найденный id и подставьте его в следующий запрос. В примере используется число 3; если база создавала записи раньше, идентификатор может быть другим.
UPDATE contacts
SET phone = '+79990000003'
WHERE id = 3
RETURNING id, name, email, phone;Проверка: RETURNING покажет изменённую строку, а сообщение будет вида UPDATE 1. Если вы получили UPDATE 0, строка с таким id не найдена — это повод проверить идентификатор, а не убирать WHERE.
Шаг 5. Удалите одну строку безопасно
Удаление необратимо на уровне обычного SQL-запроса, если у вас нет резервной копии или транзакции. Сначала выполните удаление в транзакции и верните удалённую строку на экран.
BEGIN;
DELETE FROM contacts
WHERE email = 'ilya@example.com'
RETURNING id, name, email;
SELECT id, name, email
FROM contacts
ORDER BY id;
COMMIT;Проверка: удалённый контакт должен появиться в результате RETURNING, но отсутствовать в последующем SELECT. Если результат неверен, вместо COMMIT выполните ROLLBACK до закрытия транзакции.
Шаг 6. Проверьте итоговые данные
Финальная выборка не меняет таблицу и показывает, что осталось после всех операций.
SELECT id, name, email, phone, created_at
FROM contacts
ORDER BY id;Проверка: в тестовой таблице должны остаться Анна Петрова и Мария Орлова с обновлённым телефоном. Если строки отличаются, повторите шаги на тестовой таблице или пересоздайте её блоком из шага 1.
Если не получилось
ERROR: duplicate key value violates unique constraint. В таблице уже есть такой адрес электронной почты. ВыполнитеSELECT id, email FROM contacts WHERE email = '...', затем выберите другой адрес или обновите существующую строку.ERROR: null value in column ... violates not-null constraint. В обязательный столбец передалиNULLили не указали его. Добавьте значение либо измените схему только после проверки требований приложения.ERROR: permission denied for table contacts. У текущего пользователя нет прав на таблицу. Подключитесь под владельцем или попросите администратора выдать необходимые права; не используйте суперпользователя в приложении.UPDATE 0илиDELETE 0. Условие не нашло строку. Проверьте тип и значение идентификатора, пробелы в email и текущую базу подключения.ERROR: update or delete on table ... violates foreign key constraint. На строку ссылается другая таблица. Сначала разберитесь с зависимыми записями и правилами внешнего ключа; удалять данные принудительно опасно.
Что важно изменить перед продом
Пример предназначен для ручной проверки и простого CRUD. В приложении не собирайте SQL конкатенацией строк: передавайте значения через параметры драйвера или ORM. Это защищает от SQL-инъекций и корректно обрабатывает кавычки в именах.
Для массового обновления сначала запускайте проверочный SELECT с тем же условием WHERE. Затем выполняйте UPDATE внутри транзакции и проверяйте число изменённых строк. Для удаления особенно полезны резервная копия, журналирование и явное подтверждение операции.
Отдельная тема — мягкое удаление, когда строку не удаляют, а помечают полем вроде deleted_at. Здесь рассматриваются только физические операции INSERT, UPDATE и DELETE.
Что делать дальше
Подключите эти запросы к тестовому экрану приложения и добавьте проверки количества изменённых строк. В PostgreSQL 16 отдельно изучите ограничения UNIQUE, внешние ключи и транзакции в официальной документации. В проде наблюдайте за ошибками ограничений, длительностью транзакций и количеством затронутых строк: именно эти показатели раньше всего показывают, что CRUD-операция стала опасной.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: PostgreSQL 16 Documentation: Data Manipulation, PostgreSQL 16 Documentation: SQL Commands
Частые вопросы
Можно ли выполнить UPDATE или DELETE без WHERE?
Что делать, если я не знаю id строки?
Что произойдёт, если запрос не сработал в середине транзакции?
Подойдёт ли эта инструкция для PostgreSQL 14 или другой версии?
Почему UPDATE или DELETE не изменили ни одной строки?
Можно ли удалять строки в рабочей базе напрямую?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.