В SQL, ако искате да премахнете колона от таблица, трябва да използвате ALTER TABLE
изявление с DROP COLUMN
клауза.
Това премахва колоната и всички нейни данни.
Синтаксис
Синтаксисът е така:
ALTER TABLE table_name
DROP COLUMN column_name;
Някои RDBMS приемат незадължителен IF EXISTS
аргумент, което означава, че няма да върне грешка, ако колоната не съществува.
Някои RDBMS също приемат по избор CASCADE
и RESTRICT
аргументи, които определят какво да се прави, ако колоната има някакви зависимости. Вижте по-долу за повече информация.
Пример
Ето пример за демонстрация.
ALTER TABLE Products
DROP COLUMN ProductDescription;
Това премахва ProductDescription
колона от Products
таблица.
IF EXISTS
Аргумент
В зависимост от вашата RDBMS, може да сте в състояние да използвате IF EXISTS
аргумент, който условно пуска колоната само ако тя вече съществува.
Предимството от това е, че няма да получите грешка, ако колоната не съществува.
Пример:
ALTER TABLE Products
DROP COLUMN IF EXISTS ProductDescription;
Ограничаване на промяната
В зависимост от вашата RDBMS, може да сте в състояние да използвате CASCADE
и RESTRICT
аргументи, за да укажете какво да направите, ако колоната има някакви зависимости, като външни ключове или изгледи.
RESTRICT
обикновено е поведението по подразбиране, така че ако не посочите нито един от тези аргументи, СУБД ще откаже да пусне колоната, ако има зависими обекти.
Пример:
ALTER TABLE Products
DROP COLUMN ProductDescription RESTRICT;
Когато използвате горния израз, ако колоната има някакви зависимости, операцията за пускане ще се провали и ще получите грешка.
Ето грешката, която получавам в PostgreSQL, когато се опитвам да пусна таблица, която е посочена от изглед:
cannot drop column productdescription of table products because other objects depend on it
Каскадна промяна
Използване на CASCADE
опция ще доведе до отпадане на зависими обекти.
Ето какво се случва, ако променя предишния пример на CASCADE
:
ALTER TABLE Products
DROP COLUMN ProductDescription CASCADE;
Резултат:
NOTICE: drop cascades to view vproducts Commands completed successfully
В този случай колоната беше премахната и получих съобщение, обясняващо, че изгледът се нарича vproducts
също отпадна.
CASCADE
и RESTRICT
се поддържат в PostgreSQL, но не и в SQL Server или MySQL. И двете ключови думи могат да се използват в MariaDB, но нямат никакъв ефект.
Oracle приема CASCADE CONSTRAINTS
клауза, която премахва всички ограничения на външния ключ, които се отнасят до първичните и уникалните ключове, дефинирани в изпуснатите колони, както и всички ограничения за няколко колони, дефинирани в изпуснатите колони.
Изпускане на няколко колони
Някои RDBM ви позволяват да пуснете няколко колони в рамките на един ALTER TABLE
изявление. Синтаксисът варира между RDBMS.
В SQL Server можете просто да изброите всяка колона, разделена със запетая:
ALTER TABLE t1
DROP COLUMN c1, c2;
В други RDBMS (като MySQL и PostgreSQL) ще трябва да пренапишете DROP COLUMN
за всяка колона:
ALTER TABLE t1
DROP COLUMN c1, DROP COLUMN c2;
Обърнете внимание, че този синтаксис е разширение към SQL и не отговаря на стандарта на SQL да има само един DROP
клауза за ALTER TABLE
изявление.
Изхвърлете последната колона
Някои RDBM ви позволяват да пуснете последната колона в таблицата, като по този начин оставяте празна таблица без колони. Това е разширение на стандарта SQL (което не позволява таблици с нулеви колони).
Например в PostgreSQL използвах следното изявление, за да пусна последната останала колона в таблицата
ALTER TABLE t1
DROP COLUMN c3;
Резултат:
Commands completed successfully
Но в SQL Server, ако направя същото:
ALTER TABLE t1
DROP COLUMN c1, c2, c3;
Резултат:
Msg 4923, Level 16, State 1, Line 1 ALTER TABLE DROP COLUMN failed because 'c3' is the only data column in table 't1'. A table must have at least one data column.
Имайте предвид, че въпреки формулировката на това съобщение за грешка, c3 не беше единствената останала колона. Всъщност имаше три колони. Въпреки това, c3 щеше да бъде последният останал, ако другите две бяха изпуснати. В този случай нито една от трите колони всъщност не е изпусната.
Така или иначе, дори и да изпусна другите две, SQL Server ще откаже да откаже последния.
MySQL също отказва да пусне последната колона в таблица.
Ако намерението ви е да изхвърлите таблицата, използвайте DROP TABLE
.
Ограничения от RDBMS
Въпреки че основният DROP COLUMN
Синтаксисът е доста сходен в повечето от основните RDBMS, всяка RDBMS има склонност да има свои собствени ограничения за това кога дадена колона ще или няма да бъде отпаднала.
Ето някои от ограниченията от някои от основните RDBMS.
SQL сървър
Колоната не може да бъде изпусната, когато е:
- Използва се в индекс, независимо дали като ключова колона или като
INCLUDE
- Използва се в
CHECK
,FOREIGN KEY
,UNIQUE
, илиPRIMARY KEY
ограничение. - Свързано с по подразбиране, което е дефинирано с
DEFAULT
ключова дума или свързан към обект по подразбиране. - Обвързано с правило.
Източник за SQL Server:https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql
MySQL
Ако колоните бъдат отхвърлени от таблица, колоните също се премахват от всеки индекс, от който са част. Ако всички колони, които съставляват индекс, бъдат премахнати, индексът също отпада.
Източник за MySQL:https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
PostgreSQL
Индексите и ограниченията на таблицата, включващи колоната, също ще бъдат отпаднати автоматично.
Многовариантните статистически данни, отнасящи се до изпуснатата колона, също ще бъдат премахнати, ако премахването на колоната би накарало статистиката да съдържа данни само за една колона.
Ще трябва да използвате CASCADE
ако нещо извън таблицата зависи от колоната, например външни ключове или изгледи.
Източник за PostgreSQL:https://www.postgresql.org/docs/current/sql-altertable.html
SQLite
SQLite не поддържа DROP COLUMN
синтаксис. Не можете да пуснете колона в SQLite.
Ако трябва да пуснете колона в SQLite, препоръчително е да следвате процеса от 12 стъпки, препоръчан в документацията на SQLite.
Източник за SQLite:https://sqlite.org/lang_altertable.html#otheralter
MariaDB
Ако колоната е част от който и да е индекс, колоната ще бъде премахната от тях, освен ако едновременно добавите нова колона с идентично име. Индексът ще бъде премахнат, ако всички колони от индекса са премахнати. Ако колоната е била използвана в изглед или задействане, ще получите грешка следващия път, когато се осъществи достъп до изгледа или тригера.
От MariaDB 10.2.8 пускане на колона, която е част от UNIQUE
с много колони ограничение не е разрешено.
MariaDB приема RESTRICT
и CASCADE
за да се улесни пренасянето от други системи за бази данни, но в MariaDB те не правят нищо.
MariaDB 10.4.0 поддържа незабавен DROP COLUMN
. DROP COLUMN
на индексирана колона би означавало DROP INDEX
(и в случай на не-UNIQUE
индекс с няколко колони, вероятно ADD INDEX
). Те няма да бъдат разрешени с ALGORITHM=INSTANT
, но за разлика от преди, те могат да бъдат разрешени с ALGORITHM=NOCOPY
.
Източник за MariaDB:https://mariadb.com/kb/en/alter-table/#drop-column