Медиаблог /

Как работать с ALTER TABLE в SQL: пошаговое руководство с примерами для всех СУБД

18 сентября 2026

Как работать с ALTER TABLE в SQL: пошаговое руководство с примерами для всех СУБД

ALTER TABLE — оператор языка DDL (Data Definition Language, язык определения данных), который изменяет структуру существующей таблицы без удаления хранящихся данных. С его помощью добавляют и убирают столбцы, меняют типы данных, переименовывают поля и управляют ограничениями целостности. Именно это отличает ALTER TABLE от «ядерного» варианта — DROP TABLE с последующим пересозданием: данные остаются на месте, структура меняется «на ходу».

Схема базы данных с таблицами и структурой ALTER TABLE SQL

В статье разбираем шесть ключевых операций: ADD COLUMN, DROP COLUMN, MODIFY/ALTER COLUMN, RENAME COLUMN, RENAME TABLE, ADD/DROP CONSTRAINT. Для каждой — рабочий SQL-код с комментариями, объяснение поведения и типичные ошибки. Завершает статью матрица совместимости из 11 операций для MySQL, PostgreSQL, SQL Server, Oracle и SQLite — удобный справочник при переходе между базами данных. Если вам нужен конкретный раздел, используйте заголовки как навигацию.

image

Учитесь бесплатно за счёт государства

Экономия до 100 000 ₽ на любой программе

Выбрать курс

Что такое ALTER TABLE в SQL

ALTER TABLE входит в группу DDL-операторов — наряду с CREATE TABLE, DROP TABLE и TRUNCATE. Принципиальное различие между DDL и DML (Data Manipulation Language, язык манипуляции данными): DML-операторы — INSERT, UPDATE, DELETE — работают со строками внутри таблицы, DDL меняет саму схему: добавляет столбцы, назначает ограничения, переименовывает объекты.

Оператор ALTER TABLE нужен, когда таблица уже содержит данные, но её структура перестала соответствовать задаче. Появилось новое поле, изменился тип данных, требуется ввести ограничение уникальности — пересоздавать таблицу с нуля и заново мигрировать данные дорого и рискованно. ALTER TABLE решает задачу без лишних движений.

Шесть операций, которые разбирает эта статья:

  1. ADD COLUMN — добавление нового столбца;
  2. DROP COLUMN — удаление столбца вместе с данными;
  3. MODIFY / ALTER COLUMN — изменение типа данных, размера, допустимости NULL;
  4. RENAME COLUMN — переименование столбца;
  5. RENAME TABLE — переименование таблицы;
  6. ADD / DROP CONSTRAINT — управление ограничениями: PRIMARY KEY, FOREIGN KEY, CHECK, UNIQUE.

Важный технический момент: в большинстве СУБД ALTER TABLE накладывает блокировку Schema Modification Lock (Sch-M) на всё время операции. Параллельные запросы к таблице ждут завершения. В высоконагруженных системах это критично — SQL Server 2016+ поддерживает режим WITH (ONLINE = ON) для части операций, что сводит время блокировки к минимуму.

Синтаксис ALTER TABLE: базовая структура

Универсальная схема оператора:

ALTER TABLE table_name

{operation};

Где table_name — имя существующей таблицы, operation — конкретное действие: ADD, DROP, MODIFY, ALTER COLUMN и другие.

Минимальный рабочий пример — добавление столбца в таблицу customers:

— Добавляем столбец phone в таблицу customers

ALTER TABLE customers — указываем таблицу для изменения

ADD phone VARCHAR(20) NULL; — ADD + имя столбца + тип данных + допустимость NULL

Разбор по частям:

  • ALTER TABLE customers — выбираем таблицу customers;
  • ADD phone — добавляем новый столбец с именем phone;
  • VARCHAR(20) — тип данных: строка переменной длины до 20 символов;
  • NULL — явно разрешаем пустые значения; для всех существующих строк столбец заполнится NULL автоматически.

Слово COLUMN в большинстве СУБД необязательно — ADD phone VARCHAR(20) и ADD COLUMN phone VARCHAR(20) равнозначны. Добавляйте его для читаемости кода. Синтаксис конкретной операции варьируется между СУБД: MySQL использует MODIFY COLUMN, SQL Server — ALTER COLUMN, PostgreSQL — ALTER COLUMN … TYPE … USING. Все различия разобраны в соответствующих разделах ниже.

Инфографика шесть операций ALTER TABLE в языке SQL

Что нужно подготовить перед изменением таблицы

Изменение структуры таблицы в продуктивной базе — необратимая или трудно обратимая операция. DROP COLUMN удаляет данные навсегда, изменение типа может усечь значения, а неверный порядок операций ломает зависимые объекты. Перед выполнением ALTER TABLE стоит пройти короткий чек-лист:

  • Резервная копия базы данных — обязательна, особенно перед DROP COLUMN и изменением типов данных. Без резервной копии откат невозможен.
  • Проверка зависимых объектов — индексы, представления (views), хранимые процедуры и триггеры могут ссылаться на изменяемый столбец. Их нужно обновить после операции.
  • Анализ индексов и ключей — перед удалением столбца сначала удаляют индексы и ограничения, которые от него зависят, иначе СУБД вернёт ошибку.
  • Тест на dev-базе — выполните операцию на тестовой копии, убедитесь в корректном результате и отсутствии побочных эффектов.
  • Оценка блокировок таблицы — в нагруженной системе планируйте ALTER TABLE на период низкого трафика или используйте онлайн-режим, если СУБД его поддерживает.

Зависимости столбца проверяют через системные представления. В SQL Server — через sys.columns и sys.objects, в MySQL и PostgreSQL — через INFORMATION_SCHEMA.COLUMNS:

— Проверяем, в каких таблицах есть нужный столбец (MySQL, PostgreSQL, SQL Server)

SELECT TABLE_NAME, COLUMN_NAME

FROM INFORMATION_SCHEMA.COLUMNS

WHERE TABLE_SCHEMA = ‘your_database’

AND COLUMN_NAME = ‘target_column’;

В Oracle аналогичную роль играет ALL_TAB_COLUMNS. SQLite не имеет полноценного INFORMATION_SCHEMA — зависимости отслеживают вручную через PRAGMA table_info(table_name).

Чек-лист что проверить перед выполнением ALTER TABLE в SQL

Шаг 1 — Добавление столбца: ADD COLUMN

Добавление нового столбца — самая частая операция ALTER TABLE. Общий синтаксис одинаков во всех основных СУБД:

ALTER TABLE table_name

ADD [COLUMN] column_name data_type [constraints];

Слово COLUMN необязательно, но делает код читаемее. Ключевое поведение, которое нужно помнить: новый столбец добавляется в конец таблицы. Единственное исключение — MySQL, который поддерживает ключевые слова FIRST и AFTER для управления позицией. Все остальные СУБД — строго в конец.

Далее разбираем три сценария: добавление столбца с NULL, добавление обязательного поля в непустую таблицу и позиционирование в MySQL.

Добавление столбца, допускающего NULL

Самый простой вариант — добавить необязательное поле:

— Добавляем email в таблицу users

ALTER TABLE users

ADD email VARCHAR(255) NULL;

После выполнения у всех существующих строк в поле email будет значение NULL. Никаких дополнительных действий не требуется. Поведение одинаково во всех СУБД. Схема «до и после»:

id
name
email
1 Иван NULL
2 Мария NULL

Новые строки можно вставлять без указания email — столбец автоматически получит NULL:

INSERT INTO users (name) VALUES (‘Пётр’);

— В результате: id=3, name=’Пётр’, email=NULL

Если хотите сразу задать значение по умолчанию для новых строк — добавьте DEFAULT:

ALTER TABLE users

ADD email VARCHAR(255) NULL DEFAULT ‘не указан’;

Добавление NOT NULL столбца в непустую таблицу

Одна из самых распространённых ошибок новичков — добавить обязательное поле без DEFAULT:

— ❌ Ошибка: существующие строки не получат значения для status

ALTER TABLE orders

ADD status VARCHAR(20) NOT NULL;

— MySQL: Column ‘status’ cannot be null

— SQL Server: Cannot insert the value NULL into column ‘status’

— PostgreSQL: column «status» of relation «orders» contains null values

Правильный вариант — указать DEFAULT для существующих строк:

— ✅ Все существующие строки получат значение ‘pending’

ALTER TABLE orders

ADD status VARCHAR(20) NOT NULL DEFAULT ‘pending’;

Когда СУБД выполняет ADD NOT NULL DEFAULT, механизм такой: сначала добавляется столбец, затем все существующие строки получают значение из DEFAULT, после чего применяется ограничение NOT NULL. Без DEFAULT применить NOT NULL некуда — строки остаются без значения, и ограничение нарушается ещё до первой вставки.

SQL Server — WITH VALUES. В SQL Server ключевое слово WITH VALUES явно применяет умолчание к уже существующим строкам:

ALTER TABLE orders

ADD status VARCHAR(20) NOT NULL

CONSTRAINT df_orders_status DEFAULT ‘pending’ WITH VALUES;

Без WITH VALUES в SQL Server DEFAULT применяется только к новым строкам — существующие могут нарушить NOT NULL. Всегда указывайте WITH VALUES при добавлении NOT NULL столбца в непустую таблицу через SQL Server.

Позиционирование нового столбца в MySQL (FIRST / AFTER)

MySQL — единственная из основных СУБД, которая позволяет управлять позицией нового столбца:

— Добавить столбец в начало таблицы

ALTER TABLE users

ADD id_external INT FIRST;

— Добавить столбец после конкретного поля

ALTER TABLE users

ADD middle_name VARCHAR(100) AFTER first_name;

PostgreSQL, SQL Server и Oracle позиционирование через ALTER TABLE не поддерживают — новый столбец всегда добавляется последним. Если порядок столбцов принципиален в этих СУБД, пересоздайте таблицу через CREATE TABLE AS SELECT с нужным порядком полей. На практике порядок столбцов для запросов не важен — SELECT всегда можно написать с нужным порядком полей; визуальные инструменты типа pgAdmin или DBeaver также позволяют настроить отображение.

Шаг 2 — Удаление столбца: DROP COLUMN

DROP COLUMN удаляет столбец вместе со всеми хранящимися в нём данными. Операция необратима без резервной копии:

ALTER TABLE users

DROP COLUMN middle_name;

Синтаксис одинаков в MySQL, PostgreSQL, SQL Server и Oracle. SQLite до версии 3.35.0 DROP COLUMN не поддерживает совсем — для таких случаев используется workaround с пересозданием таблицы, аналогичный описанному ниже для PRIMARY KEY.

SQL Server: после DROP COLUMN дисковое пространство не освобождается немедленно. Страницы данных продолжают занимать место на диске, пока не произойдёт перестройка кластеризованного индекса командой ALTER INDEX … REBUILD. В высоконагруженных системах это учитывают при планировании обслуживания.

Если вы изучаете SQL и хотите разобраться не только с синтаксисом ALTER TABLE, но и с проектированием баз данных с нуля, аналитикой и информационными системами в целом — в рамках федерального проекта «Активные меры содействия занятости» доступно обучение по программе «Специалист по аналитике и базам данных в информационных системах» без отрыва от работы и без вложений. Подробнее — в каталоге программ обучения.

Проверка зависимостей перед удалением

Если на удаляемый столбец ссылается индекс, ограничение или внешний ключ — СУБД вернёт ошибку. Правильный порядок действий: сначала удалить зависимые объекты, затем сам столбец.

Пример для SQL Server — удаляем столбец email, на котором есть ограничение DEFAULT и уникальный индекс:

— Шаг 1: удаляем ограничение DEFAULT (по имени)

ALTER TABLE users

DROP CONSTRAINT df_users_email;

— Шаг 2: удаляем уникальный индекс

DROP INDEX IX_users_email ON users;

— Шаг 3: теперь удаляем столбец

ALTER TABLE users

DROP COLUMN email;

Как найти имена ограничений, если они неизвестны:

— SQL Server: список ограничений на таблице

SELECT name, type_desc

FROM sys.objects

WHERE parent_object_id = OBJECT_ID(‘users’)

AND type IN (‘D’, ‘UQ’, ‘F’, ‘PK’, ‘C’);

В MySQL несколько операций объединяют в одном ALTER TABLE — это эффективнее последовательных запросов:

— MySQL: дропаем индекс и столбец за один проход

ALTER TABLE users

DROP INDEX idx_users_email,

DROP COLUMN email;

SQLite до версии 3.35.0: DROP COLUMN не поддерживается ни в каком виде. Если версия SQLite старше — единственный путь тот же, что и для изменения PRIMARY KEY: создать новую таблицу без нужного столбца, скопировать данные, удалить старую таблицу, переименовать новую.

Шаг 3 — Изменение столбца: MODIFY / ALTER COLUMN

Изменение существующего столбца — наиболее диалектно-разнообразная операция ALTER TABLE. Ключевые слова в разных СУБД:

  • MySQL, Oracle — MODIFY COLUMN / MODIFY;
  • SQL Server — ALTER COLUMN;
  • PostgreSQL — ALTER COLUMN … TYPE … USING.

Операция позволяет изменить тип данных, длину строки, допустимость NULL — не трогая при этом хранящиеся значения (при условии совместимости типов).

Изменение типа данных столбца

Безопасные расширения типов — операции, при которых данные не теряются:

— INT → BIGINT: расширение диапазона, данные не теряются

— SQL Server

ALTER TABLE orders

ALTER COLUMN order_id BIGINT;

— VARCHAR(50) → VARCHAR(200): расширение длины

— MySQL

ALTER TABLE products

MODIFY COLUMN description VARCHAR(200);

— PostgreSQL

ALTER TABLE products

ALTER COLUMN description TYPE VARCHAR(200);

Сужение — другое дело. VARCHAR(200) → VARCHAR(10) приведёт к усечению строк длиннее 10 символов. СУБД либо вернёт ошибку, либо молча обрежет данные. Перед сужением убедитесь в реальных данных:

— Проверяем максимальную длину значений перед сужением (SQL Server)

SELECT MAX(LEN(description)) AS max_len FROM products;

PostgreSQL — обязательный USING. При несовместимом преобразовании типов PostgreSQL не выполнит операцию без явного указания правила конвертации через USING:

— ❌ Ошибка: PostgreSQL не может автоматически преобразовать VARCHAR → NUMERIC

ALTER TABLE orders

ALTER COLUMN total TYPE NUMERIC;

— ERROR: column «total» cannot be cast automatically to type numeric

— ✅ Правильно: указываем USING с выражением преобразования

ALTER TABLE orders

ALTER COLUMN total TYPE NUMERIC USING total::NUMERIC;

Оператор :: в PostgreSQL — синтаксический сахар для приведения типа (аналог CAST(total AS NUMERIC)). После USING можно написать любое SQL-выражение: функцию, условие, математическую операцию — это мощный инструмент для нетривиальных преобразований типов данных.

Изменение NULL → NOT NULL

Перед изменением допустимости NULL необходимо убедиться, что в столбце нет пустых значений:

— Шаг 1: заменяем NULL на значение по умолчанию

UPDATE users

SET phone = ‘не указан’

WHERE phone IS NULL;

— Шаг 2: меняем ограничение столбца

— SQL Server

ALTER TABLE users

ALTER COLUMN phone VARCHAR(20) NOT NULL;

— MySQL

ALTER TABLE users

MODIFY COLUMN phone VARCHAR(20) NOT NULL;

— PostgreSQL — лаконичный синтаксис без повторения типа

ALTER TABLE users

ALTER COLUMN phone SET NOT NULL;

— Снятие NOT NULL в PostgreSQL

ALTER TABLE users

ALTER COLUMN phone DROP NOT NULL;

SET NOT NULL и DROP NOT NULL в PostgreSQL — удобные сокращения: не нужно повторять тип данных и другие атрибуты столбца. Без предварительного UPDATE существующие NULL нарушат ограничение — операция завершится ошибкой во всех СУБД.

Шаг 4 — Переименование: RENAME COLUMN и RENAME TABLE

Нативный синтаксис RENAME COLUMN поддерживается в MySQL 8.0+, PostgreSQL, Oracle 9i+ и SQLite 3.25+:

— MySQL 8+, PostgreSQL, Oracle 9i+, SQLite 3.25+

ALTER TABLE users

RENAME COLUMN full_name TO display_name;

Переименование таблицы:

— MySQL, PostgreSQL, SQLite

ALTER TABLE old_table_name

RENAME TO new_table_name;

— Oracle

ALTER TABLE old_table_name

RENAME TO new_table_name;

SQL Server — исключение: нативного RENAME COLUMN в T-SQL нет и никогда не было. Переименование реализуется только через системную хранимую процедуру (stored procedure) sp_rename.

Переименование в SQL Server через sp_rename

sp_rename — системная хранимая процедура SQL Server для переименования объектов базы данных: таблиц, столбцов, индексов и других объектов.

— Переименование столбца: ‘таблица.старое_имя’, ‘новое_имя’, ‘COLUMN’

EXEC sp_rename ‘users.full_name’, ‘display_name’, ‘COLUMN’;

— Переименование таблицы: достаточно двух аргументов

EXEC sp_rename ‘old_table_name’, ‘new_table_name’;

— Переименование индекса

EXEC sp_rename ‘users.IX_users_email’, ‘IX_users_email_new’, ‘INDEX’;

Первый аргумент — полный путь к объекту (таблица.столбец), второй — новое имя, третий — тип объекта: ‘COLUMN’, ‘INDEX’ или ‘OBJECT’ (для таблиц и процедур).

СУБД
Синтаксис
Версия
MySQL ALTER TABLE t RENAME COLUMN old TO new; 8.0+
PostgreSQL ALTER TABLE t RENAME COLUMN old TO new; все версии
Oracle ALTER TABLE t RENAME COLUMN old TO new; 9i+
SQLite ALTER TABLE t RENAME COLUMN old TO new; 3.25+
SQL Server EXEC sp_rename ‘table.old’, ‘new’, ‘COLUMN’; все версии

⚠️ После переименования столбца или таблицы обновите все зависимые объекты вручную: представления, хранимые процедуры, триггеры и прикладной код. СУБД не переименовывает ссылки автоматически — это источник трудноуловимых ошибок. В SQL Server после sp_rename система выдаёт предупреждение «Caution: Changing any part of an object name could break scripts and stored procedures» — не игнорируйте его.

Шаг 5 — Управление ограничениями: ADD / DROP CONSTRAINT

Ограничения (constraints) — правила целостности данных, которые СУБД контролирует автоматически. ALTER TABLE позволяет добавлять и удалять их в уже существующих таблицах:

— Общий синтаксис именованного ограничения

ALTER TABLE table_name

ADD CONSTRAINT constraint_name constraint_type (columns);

Именованные ограничения — best practice. Автоматически сгенерированные имена типа FK__orders__user_id__3A4CA8FD неудобны в работе: сложно читать, невозможно запомнить. Используйте соглашение об именовании (naming convention): pk_ для первичных ключей, fk_ для внешних, chk_ для CHECK, uq_ для UNIQUE.

WITH CHECK (поведение по умолчанию) — проверяет ограничение на уже существующих строках при добавлении. WITH NOCHECK — добавляет ограничение только для новых строк, не проверяя существующие данные. Используется при добавлении FOREIGN KEY в таблицу с данными, которые заведомо соответствуют ограничению, — ускоряет операцию, но переносит риск на существующие данные.

Добавление PRIMARY KEY, FOREIGN KEY, CHECK, UNIQUE

— PRIMARY KEY

ALTER TABLE orders

ADD CONSTRAINT pk_orders PRIMARY KEY (order_id);

— FOREIGN KEY с явной проверкой существующих строк

ALTER TABLE orders

ADD CONSTRAINT fk_orders_user

FOREIGN KEY (user_id) REFERENCES users(id)

WITH CHECK;

— CHECK: ограничение на допустимые значения

Хотите сменить профессию или повысить квалификацию?

Федеральный проект «Активные меры содействия занятости» даёт возможность пройти обучение бесплатно за счёт государства

  • Программы от ведущих вузов России — от 2 месяцев
  • Удостоверение или диплом установленного образца
  • Центр карьеры: 7 500+ вакансий, помощь с трудоустройством
Оставить заявку
image

ALTER TABLE products

ADD CONSTRAINT chk_products_price CHECK (price > 0);

— UNIQUE: уникальность значений в столбце

ALTER TABLE users

ADD CONSTRAINT uq_users_email UNIQUE (email);

Составной PRIMARY KEY — через список столбцов:

— Составной первичный ключ из двух столбцов

ALTER TABLE order_items

ADD CONSTRAINT pk_order_items PRIMARY KEY (order_id, product_id);

Удаление ограничений: DROP CONSTRAINT

— SQL Server, PostgreSQL, Oracle — универсальный синтаксис

ALTER TABLE orders

DROP CONSTRAINT fk_orders_user;

— MySQL: особый синтаксис для PRIMARY KEY и FOREIGN KEY

ALTER TABLE orders

DROP PRIMARY KEY;

ALTER TABLE orders

DROP FOREIGN KEY fk_orders_user;

— MySQL: DROP INDEX для UNIQUE-ограничений

ALTER TABLE users

DROP INDEX uq_users_email;

Как найти имя ограничения, если оно неизвестно:

— MySQL, PostgreSQL, SQL Server

SELECT CONSTRAINT_NAME, CONSTRAINT_TYPE

FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS

WHERE TABLE_NAME = ‘orders’

AND TABLE_SCHEMA = ‘your_database’;

В Oracle используйте USER_CONSTRAINTS или ALL_CONSTRAINTS.

Матрица совместимости ALTER TABLE по СУБД

Переключаясь между СУБД, легко ошибиться в синтаксисе: то, что работает в MySQL, вызывает ошибку в PostgreSQL или SQLite. Матрица ниже — быстрый справочник по поддержке 11 ключевых операций в пяти СУБД. Держите её под рукой при миграции кода между диалектами SQL.

Условные обозначения: ✅ — поддерживается нативно; ⚠️ — поддерживается с оговорками; ❌ — не поддерживается.

Операция
MySQL
PostgreSQL
SQL Server
Oracle
SQLite
ADD COLUMN NULL ✅ ✅ ✅ ✅ ✅
ADD COLUMN NOT NULL DEFAULT ✅ ✅ ✅ WITH VALUES ✅ ✅
DROP COLUMN ✅ ✅ ✅ ✅ ⚠️ 3.35+
MODIFY / ALTER COLUMN TYPE ✅ MODIFY ⚠️ USING ✅ ALTER COLUMN ✅ MODIFY ❌
ALTER COLUMN NULL/NOT NULL ✅ ✅ SET/DROP ✅ ✅ ❌
RENAME COLUMN ✅ 8.0+ ✅ ❌ → sp_rename ✅ 9i+ ✅ 3.25+
RENAME TABLE ✅ ✅ ❌ → sp_rename ✅ ✅
ADD PRIMARY KEY ✅ ✅ ✅ ✅ ❌ workaround
ADD FOREIGN KEY ✅ ✅ ✅ ✅ ⚠️ синтаксис есть, не применяется
ADD CHECK ✅ ✅ ✅ ✅ ⚠️ синтаксис есть, не применяется
ONLINE-режим ⚠️ InnoDB ❌ ✅ 2016+ ❌ ❌

Вывод из матрицы: SQLite — наиболее ограниченная СУБД по возможностям ALTER TABLE; SQL Server — наиболее расширенная за счёт ONLINE-операций и гибкого sp_rename. Всегда проверяйте версию СУБД перед использованием новых возможностей: поведение SQLite принципиально меняется на версиях 3.25 (появляется RENAME COLUMN) и 3.35 (появляется DROP COLUMN).

Особенности ALTER TABLE в разных СУБД

Стандарт SQL-92 определяет базовый синтаксис ALTER TABLE, но каждый диалект SQL добавляет собственные расширения — и собственные ограничения. В этом разделе — ключевые особенности пяти СУБД, которые нужно знать при написании реального кода.

SQL Server — T-SQL, ONLINE-операции и sp_rename

Добавление NOT NULL столбца в непустую таблицу:

ALTER TABLE orders

ADD created_at DATETIME NOT NULL

CONSTRAINT df_orders_created_at DEFAULT GETDATE() WITH VALUES;

GETDATE() — встроенная функция T-SQL, возвращающая текущую дату и время. WITH VALUES применяет DEFAULT ко всем существующим строкам.

ALTER COLUMN с ONLINE-режимом — SQL Server 2016+:

— Изменение типа с минимальной блокировкой таблицы

ALTER TABLE large_table

ALTER COLUMN description VARCHAR(500)

WITH (ONLINE = ON);

ONLINE = ON — блокировка действует только в самом начале и конце операции (короткие Sch-M). Таблица остаётся доступной для чтения и записи почти всё время. Без ONLINE = ON блокировка длится всю операцию — для таблиц с миллионами строк это может занять минуты.

RENAME — только через sp_rename:

— Переименование столбца

EXEC sp_rename ‘orders.created_at’, ‘order_date’, ‘COLUMN’;

— Переименование таблицы

EXEC sp_rename ‘orders’, ‘customer_orders’;

Ограничения ALTER COLUMN в SQL Server:

  • нельзя изменить вычисляемый (computed) столбец;
  • нельзя изменить столбец с атрибутом IDENTITY (автоинкремент);
  • нельзя напрямую изменить столбец типа LOB (text, ntext, image) — сначала нужно сменить тип на поддерживаемый.

MySQL — MODIFY COLUMN и FIRST / AFTER

MySQL использует MODIFY COLUMN вместо ALTER COLUMN:

— Изменение типа, размера и ограничений

ALTER TABLE products

MODIFY COLUMN price DECIMAL(10,2) NOT NULL DEFAULT 0.00;

С MySQL 8.0 доступен нативный RENAME COLUMN — без sp_rename и без пересоздания таблицы:

ALTER TABLE users

RENAME COLUMN full_name TO display_name;

Сила MySQL — возможность объединять несколько операций в одном ALTER TABLE. Таблица перестраивается один раз вместо N раз:

— Четыре операции за один проход

ALTER TABLE users

ADD COLUMN avatar_url VARCHAR(500) NULL AFTER email,

MODIFY COLUMN email VARCHAR(320) NOT NULL,

RENAME COLUMN phone TO phone_number,

ADD INDEX idx_users_email (email);

Позиционирование нового столбца — только в MySQL:

ALTER TABLE users

ADD COLUMN profile_id INT FIRST; — в начало

ALTER TABLE users

ADD COLUMN bio TEXT AFTER display_name; — после конкретного поля

PostgreSQL — ALTER COLUMN TYPE … USING

PostgreSQL позволяет изменять тип данных через ALTER COLUMN … TYPE, но при несовместимом преобразовании требует явного USING:

— Преобразование VARCHAR → INTEGER с кастом через ::

ALTER TABLE logs

ALTER COLUMN status_code TYPE INTEGER USING status_code::INTEGER;

— Более сложное преобразование с функцией

ALTER TABLE users

ALTER COLUMN birth_date TYPE DATE

USING TO_DATE(birth_date, ‘DD.MM.YYYY’);

Лаконичные команды для управления допустимостью NULL:

— Установить NOT NULL

ALTER TABLE users

ALTER COLUMN email SET NOT NULL;

— Снять NOT NULL

ALTER TABLE users

ALTER COLUMN phone DROP NOT NULL;

PostgreSQL не поддерживает WITH NOCHECK для FOREIGN KEY. При добавлении FK все существующие строки проверяются автоматически — если есть нарушения, операция завершится ошибкой. Также нет ONLINE-режима: блокировка при изменении типа держится всё время операции.

Oracle — MODIFY и RENAME COLUMN

Oracle использует MODIFY без слова COLUMN:

— Изменение типа данных

ALTER TABLE employees

MODIFY salary NUMBER(12,2);

— Изменение допустимости NULL

ALTER TABLE employees

MODIFY department_id NOT NULL;

— Изменение нескольких столбцов одновременно

ALTER TABLE employees

MODIFY (

first_name VARCHAR2(100),

last_name VARCHAR2(100)

);

RENAME COLUMN доступен с Oracle 9i:

ALTER TABLE employees

RENAME COLUMN emp_no TO employee_id;

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

ALTER TABLE employees

DROP (department_id, manager_id);

SQLite — ограничения и workaround для PRIMARY KEY

SQLite поддерживает ограниченный набор операций ALTER TABLE:

  • ✅ ADD COLUMN — с ограничением: NOT NULL требует DEFAULT;
  • ✅ RENAME TABLE — с любой версии;
  • ✅ RENAME COLUMN — с версии 3.25 (2018);
  • ✅ DROP COLUMN — с версии 3.35 (2021);
  • ❌ ALTER COLUMN TYPE — не поддерживается;
  • ❌ ADD CONSTRAINT / ADD PRIMARY KEY — не поддерживается;
  • ❌ DROP CONSTRAINT — не поддерживается.

FOREIGN KEY и CHECK в SQLite принимаются синтаксически при CREATE TABLE, но при ALTER TABLE ADD CONSTRAINT работать не будут — только workaround через пересоздание таблицы.

— ❌ Ошибка: NOT NULL без DEFAULT в непустой таблице SQLite

ALTER TABLE users ADD age INTEGER NOT NULL;

— ✅ Правильно

ALTER TABLE users ADD age INTEGER NOT NULL DEFAULT 0;

Workaround для PRIMARY KEY — 4 шага:

SQLite не позволяет добавить PRIMARY KEY через ALTER TABLE — это фундаментальное ограничение архитектуры. Единственный путь — пересоздать таблицу:

— Шаг 1: создаём новую таблицу с нужной структурой и PRIMARY KEY

CREATE TABLE users_new (

id INTEGER PRIMARY KEY,

name TEXT NOT NULL,

email TEXT

);

— Шаг 2: копируем данные из старой таблицы

INSERT INTO users_new (id, name, email)

SELECT id, name, email FROM users;

— Шаг 3: удаляем старую таблицу

DROP TABLE users;

— Шаг 4: переименовываем новую таблицу

ALTER TABLE users_new RENAME TO users;

Этот подход применяется для любых структурных изменений, которые SQLite не поддерживает через ALTER TABLE: изменение типа столбца, добавление/удаление ограничений, изменение PRIMARY KEY. Рекомендуется обернуть все четыре шага в транзакцию (BEGIN TRANSACTION / COMMIT), чтобы при сбое данные не оказались в промежуточном состоянии.

Четыре шага обходного пути для изменения PRIMARY KEY в SQLite

Частые ошибки при работе с ALTER TABLE и их решения

Большинство ошибок ALTER TABLE — типовые: их допускают снова и снова при переходе между СУБД или при работе с непустыми таблицами. Разбираем пять наиболее распространённых.

Ошибка 1: ADD NOT NULL без DEFAULT

— ❌ Ошибка: существующие строки не получат значения для priority

ALTER TABLE orders ADD priority VARCHAR(10) NOT NULL;

— MySQL: Column ‘priority’ cannot be null

— SQL Server: Cannot insert the value NULL into column ‘priority’

— ✅ Решение: задать DEFAULT для существующих строк

ALTER TABLE orders ADD priority VARCHAR(10) NOT NULL DEFAULT ‘normal’;

Причина: при добавлении столбца СУБД «смотрит» на существующие строки. Если значение поставить некуда, ограничение NOT NULL нарушается немедленно, ещё до первой вставки новых данных.

Ошибка 2: DROP COLUMN с зависимостями

— ❌ Ошибка: на столбце есть уникальный индекс

ALTER TABLE users DROP COLUMN email;

— SQL Server: The object ‘IX_users_email’ is dependent on column ’email’

— PostgreSQL: column «email» of relation «users» cannot be dropped because other objects depend on it

— ✅ Решение: сначала зависимые объекты, потом столбец

ALTER TABLE users DROP CONSTRAINT uq_users_email;

DROP INDEX IX_users_email ON users; — SQL Server

ALTER TABLE users DROP COLUMN email;

Порядок всегда такой: DROP CONSTRAINT → DROP INDEX → DROP COLUMN. Нарушение порядка даёт ошибку зависимости.

Ошибка 3: RENAME COLUMN в SQL Server без sp_rename

— ❌ SQL Server не поддерживает нативный RENAME COLUMN

ALTER TABLE users RENAME COLUMN old_email TO email_address;

— Incorrect syntax near ‘RENAME’

— ✅ Только через sp_rename

EXEC sp_rename ‘users.old_email’, ’email_address’, ‘COLUMN’;

Ошибка 4: PostgreSQL без USING при несовместимых типах

— ❌ PostgreSQL не выполнит преобразование без USING

ALTER TABLE logs ALTER COLUMN status_code TYPE INTEGER;

— ERROR: column «status_code» cannot be cast automatically to type integer

— ✅ Добавляем USING с правилом преобразования

ALTER TABLE logs

ALTER COLUMN status_code TYPE INTEGER

USING status_code::INTEGER;

Ошибка 5: ADD PRIMARY KEY в SQLite

— ❌ SQLite не поддерживает ADD CONSTRAINT ни в каком виде

ALTER TABLE users ADD CONSTRAINT pk_users PRIMARY KEY (id);

— ParseError: near «CONSTRAINT»: syntax error

— ✅ Только workaround: CREATE TABLE новая → INSERT → DROP старая → RENAME

— Полный код — в разделе про SQLite выше

Помимо синтаксических ошибок встречаются и логические: изменение типа столбца без предварительной проверки реальных данных, удаление столбца, на который ссылается прикладной код, или переименование без обновления хранимых процедур. Любая из этих ситуаций нарушает работу приложения — поэтому тест на dev-базе перед ALTER TABLE на продуктиве обязателен всегда.

Часто задаваемые вопросы

Чем отличается синтаксис ALTER TABLE в MySQL, PostgreSQL и SQL Server?

MySQL использует MODIFY COLUMN, SQL Server — ALTER COLUMN, PostgreSQL — ALTER COLUMN TYPE с обязательным USING при несовместимых преобразованиях. Переименование столбца в SQL Server выполняется только через sp_rename; в остальных СУБД — нативный RENAME COLUMN. MySQL позволяет задавать позицию нового столбца через FIRST / AFTER, другие СУБД добавляют столбец строго в конец. MySQL также позволяет объединять несколько операций в одном запросе — таблица перестраивается один раз.

Как добавить PRIMARY KEY в SQLite через ALTER TABLE?

Напрямую нельзя — SQLite не поддерживает ADD CONSTRAINT. Workaround из четырёх шагов: 1) создать новую таблицу с нужным PRIMARY KEY через CREATE TABLE; 2) скопировать данные через INSERT INTO new_t SELECT * FROM old_t; 3) удалить старую таблицу DROP TABLE old_t; 4) переименовать новую через ALTER TABLE new_t RENAME TO old_t. Все четыре шага рекомендуется выполнять в одной транзакции.

Как изменить тип столбца без потери данных?

Безопасные расширения — INT→BIGINT, VARCHAR(50)→VARCHAR(200) — данные не теряются. Сужение типа или диапазона грозит усечением. В PostgreSQL при несовместимых типах обязателен USING: ALTER COLUMN col TYPE NUMERIC USING col::NUMERIC. В SQLite изменение типа данных столбца через ALTER TABLE не поддерживается вообще — нужен workaround с пересозданием таблицы. Перед изменением типа всегда проверяйте реальный диапазон значений в столбце и делайте резервную копию.

Что такое sp_rename и зачем он нужен в SQL Server?

sp_rename — системная хранимая процедура SQL Server для переименования объектов базы данных. Синтаксис для столбца: EXEC sp_rename ‘TableName.OldCol’, ‘NewCol’, ‘COLUMN’;. Она необходима потому, что SQL Server не поддерживает нативный RENAME COLUMN в операторе ALTER TABLE — в отличие от MySQL 8+, PostgreSQL и Oracle 9i+. После вызова sp_rename система выдаёт предупреждение о необходимости обновить зависимые объекты.

Что произойдёт с данными при DROP COLUMN?

Данные удаляются безвозвратно. В SQL Server дисковое пространство не освобождается немедленно — нужна перестройка кластеризованного индекса через ALTER INDEX … REBUILD. В SQLite до версии 3.35.0 DROP COLUMN не поддерживается совсем — нужен workaround с пересозданием таблицы. Перед удалением убедитесь в отсутствии зависимых индексов, ограничений и прикладного кода, который обращается к этому столбцу.

Как добавить NOT NULL столбец в непустую таблицу?

Обязательно указывайте DEFAULT: ALTER TABLE t ADD col VARCHAR(50) NOT NULL DEFAULT ‘value’;. Без DEFAULT существующие строки не получат значений — ограничение NOT NULL нарушается до первой вставки, и операция завершится ошибкой. В SQL Server дополнительно укажите WITH VALUES, чтобы DEFAULT применился к уже существующим строкам, а не только к новым.

Можно ли выполнить ALTER TABLE без блокировки таблицы?

В SQL Server 2016+ используйте ALTER COLUMN … WITH (ONLINE = ON) — таблица остаётся доступной почти всё время, короткая Sch-M-блокировка накладывается лишь в начале и конце операции. MySQL InnoDB поддерживает часть операций в онлайн-режиме, но не все. PostgreSQL и SQLite по умолчанию блокируют таблицу на всё время операции — планируйте их на период низкого трафика.

Как изменить столбец с NULL на NOT NULL?

Сначала обновите строки с NULL-значениями: UPDATE t SET col = ‘default_value’ WHERE col IS NULL;. Затем примените ограничение: в SQL Server — ALTER TABLE t ALTER COLUMN col VARCHAR(50) NOT NULL;, в MySQL — MODIFY COLUMN col VARCHAR(50) NOT NULL;, в PostgreSQL — ALTER TABLE t ALTER COLUMN col SET NOT NULL;. Без предварительного UPDATE операция завершится ошибкой — существующие NULL нарушат ограничение.

Подайте заявку —
забронируйте место в группе

45 000 мест на 2026 год. Бесплатное обучение по федеральному проекту «Активные меры содействия занятости»

  • Онлайн
  • От 2 месяцев
  • Бесплатно
  • Диплом
Учиться бесплатно
icon