Trong SQL, nếu bạn muốn xóa một cột khỏi bảng, bạn cần sử dụng ALTER TABLE
câu lệnh với DROP COLUMN
mệnh đề.
Điều đó sẽ xóa cột và tất cả dữ liệu của nó.
Cú pháp
Cú pháp như sau:
ALTER TABLE table_name
DROP COLUMN column_name;
Một số RDBMS chấp nhận IF EXISTS
tùy chọn có nghĩa là nó sẽ không trả về lỗi nếu cột không tồn tại.
Một số RDBMS cũng chấp nhận CASCADE
tùy chọn và RESTRICT
đối số, chỉ định những gì phải làm nếu cột có bất kỳ phụ thuộc nào. Xem bên dưới để biết thêm về điều này.
Ví dụ
Đây là một ví dụ để chứng minh.
ALTER TABLE Products
DROP COLUMN ProductDescription;
Thao tác này sẽ xóa ProductDescription
từ cột Products
bảng.
IF EXISTS
Đối số
Tùy thuộc vào RDBMS của bạn, bạn có thể sử dụng IF EXISTS
đối số, chỉ giảm cột theo điều kiện nếu nó đã tồn tại.
Lợi ích của việc này là bạn sẽ không gặp lỗi nếu cột không tồn tại.
Ví dụ:
ALTER TABLE Products
DROP COLUMN IF EXISTS ProductDescription;
Hạn chế thay đổi
Tùy thuộc vào RDBMS của bạn, bạn có thể sử dụng CASCADE
và RESTRICT
đối số để chỉ định phải làm gì nếu cột có bất kỳ phụ thuộc nào, chẳng hạn như khóa ngoài hoặc chế độ xem.
RESTRICT
thường là hành vi mặc định, vì vậy nếu bạn không chỉ định bất kỳ đối số nào trong số này, DBMS sẽ từ chối bỏ cột nếu có bất kỳ đối tượng phụ thuộc nào.
Ví dụ:
ALTER TABLE Products
DROP COLUMN ProductDescription RESTRICT;
Khi sử dụng câu lệnh trên, nếu cột có bất kỳ phần phụ thuộc nào, thì thao tác thả sẽ không thành công và bạn sẽ gặp lỗi.
Đây là lỗi tôi gặp phải trong PostgreSQL khi cố gắng thả một bảng được tham chiếu bởi một chế độ xem:
cannot drop column productdescription of table products because other objects depend on it
Xếp tầng thay đổi
Sử dụng CASCADE
tùy chọn này sẽ khiến mọi đối tượng phụ thuộc bị loại bỏ.
Đây là những gì sẽ xảy ra nếu tôi thay đổi ví dụ trước đó thành CASCADE
:
ALTER TABLE Products
DROP COLUMN ProductDescription CASCADE;
Kết quả:
NOTICE: drop cascades to view vproducts Commands completed successfully
Trong trường hợp này, cột đã bị xóa và tôi nhận được thông báo giải thích rằng chế độ xem được gọi là vproducts
cũng đã bị loại bỏ.
CASCADE
và RESTRICT
được hỗ trợ trong PostgreSQL, nhưng không được hỗ trợ trong SQL Server hoặc MySQL. Cả hai từ khóa đều có thể được sử dụng trong MariaDB nhưng chúng không có bất kỳ tác dụng nào.
Oracle chấp nhận CASCADE CONSTRAINTS
mệnh đề loại bỏ tất cả các ràng buộc khóa ngoại tham chiếu đến các khóa chính và khóa duy nhất được xác định trên các cột bị loại bỏ cũng như tất cả các ràng buộc đa cột được xác định trên các cột bị loại bỏ.
Thả nhiều cột
Một số RDBM cho phép bạn thả nhiều cột trong một ALTER TABLE
duy nhất tuyên bố. Cú pháp khác nhau giữa các RDBMS.
Trong SQL Server, bạn có thể chỉ cần liệt kê từng cột, được phân tách bằng dấu phẩy:
ALTER TABLE t1
DROP COLUMN c1, c2;
Trong các RDBMS khác (chẳng hạn như MySQL và PostgreSQL), bạn sẽ cần phải viết lại DROP COLUMN
cho mỗi cột:
ALTER TABLE t1
DROP COLUMN c1, DROP COLUMN c2;
Lưu ý rằng cú pháp này là một phần mở rộng của SQL và nó không tuân theo tiêu chuẩn SQL là chỉ có một DROP
mệnh đề mỗi ALTER TABLE
tuyên bố.
Thả cột cuối cùng
Một số RDBM cho phép bạn bỏ cột cuối cùng trong bảng, do đó để lại một bảng trống không có cột. Đây là một phần mở rộng của tiêu chuẩn SQL (không cho phép các bảng không có cột).
Ví dụ:trong PostgreSQL, tôi đã sử dụng câu lệnh sau để bỏ cột cuối cùng còn lại trong bảng
ALTER TABLE t1
DROP COLUMN c3;
Kết quả:
Commands completed successfully
Nhưng trong SQL Server, nếu tôi làm như vậy:
ALTER TABLE t1
DROP COLUMN c1, c2, c3;
Kết quả:
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.
Lưu ý rằng bất chấp cách diễn đạt của thông báo lỗi này, c3 không phải là cột duy nhất còn lại. Thực tế có ba cột. Tuy nhiên, c3 sẽ là cái cuối cùng còn lại nếu hai cái kia bị loại bỏ. Trong trường hợp này, không có cột nào trong số ba cột thực sự bị loại bỏ.
Dù bằng cách nào, ngay cả khi tôi bỏ hai cái kia, SQL Server sẽ từ chối bỏ cái cuối cùng.
MySQL cũng từ chối bỏ cột cuối cùng trong bảng.
Nếu ý định của bạn là bỏ bảng, hãy sử dụng DROP TABLE
.
Các hạn chế của RDBMS
Mặc dù DROP COLUMN
cơ bản cú pháp khá giống nhau trên hầu hết các RDBMS chính, mỗi RDBMS có xu hướng có các hạn chế riêng về thời điểm một cột sẽ hoặc sẽ không bị loại bỏ.
Dưới đây là một số hạn chế từ một số RDBMS chính.
Máy chủ SQL
Không thể bỏ cột khi đó là:
- Được sử dụng trong một chỉ mục, cho dù là một cột chính hay một
INCLUDE
- Được sử dụng trong
CHECK
,FOREIGN KEY
,UNIQUE
hoặcPRIMARY KEY
ràng buộc. - Được liên kết với một mặc định được xác định bằng
DEFAULT
từ khóa hoặc liên kết với một đối tượng mặc định. - Bị ràng buộc với một quy tắc.
Nguồn cho SQL Server:https://docs.microsoft.com/en-us/sql/t-sql/statements/alter-table-transact-sql
MySQL
Nếu các cột bị xóa khỏi bảng, các cột cũng bị xóa khỏi bất kỳ chỉ mục nào mà chúng là một phần. Nếu tất cả các cột tạo nên một chỉ mục bị loại bỏ, thì chỉ mục đó cũng bị loại bỏ.
Nguồn cho MySQL:https://dev.mysql.com/doc/refman/8.0/en/alter-table.html
PostgreSQL
Các chỉ mục và ràng buộc bảng liên quan đến cột cũng sẽ tự động bị loại bỏ.
Thống kê đa biến tham chiếu đến cột bị loại bỏ cũng sẽ bị xóa nếu việc xóa cột đó sẽ khiến thống kê chỉ chứa dữ liệu cho một cột duy nhất.
Bạn sẽ cần sử dụng CASCADE
nếu bất kỳ thứ gì bên ngoài bảng phụ thuộc vào cột, ví dụ:khóa ngoại hoặc chế độ xem.
Nguồn cho PostgreSQL:https://www.postgresql.org/docs/current/sql-altertable.html
SQLite
SQLite không hỗ trợ DROP COLUMN
cú pháp. Bạn không thể bỏ một cột trong SQLite.
Nếu bạn cần bỏ một cột trong SQLite, bạn nên làm theo quy trình 12 bước được đề xuất trong tài liệu SQLite.
Nguồn cho SQLite:https://sqlite.org/lang_altertable.html#otheralter
MariaDB
Nếu cột đó là một phần của bất kỳ chỉ mục nào, thì cột đó sẽ bị xóa khỏi chúng, ngoại trừ trường hợp bạn thêm cột mới có tên trùng vào cùng một lúc. Chỉ mục sẽ bị loại bỏ nếu tất cả các cột từ chỉ mục bị loại bỏ. Nếu cột được sử dụng trong một chế độ xem hoặc trình kích hoạt, bạn sẽ gặp lỗi vào lần tiếp theo khi chế độ xem hoặc trình kích hoạt được truy cập.
Từ MariaDB 10.2.8, thả một cột là một phần của UNIQUE
nhiều cột ràng buộc không được phép.
MariaDB chấp nhận RESTRICT
và CASCADE
để làm cho việc chuyển từ các hệ thống cơ sở dữ liệu khác dễ dàng hơn, nhưng trong MariaDB, chúng không làm gì cả.
MariaDB 10.4.0 hỗ trợ DROP COLUMN
tức thì . DROP COLUMN
của một cột được lập chỉ mục sẽ ngụ ý DROP INDEX
(và trong trường hợp không phải UNIQUE
chỉ mục nhiều cột, có thể là ADD INDEX
). Chúng sẽ không được phép với ALGORITHM=INSTANT
, nhưng không giống như trước đây, chúng có thể được phép với ALGORITHM=NOCOPY
.
Nguồn cho MariaDB:https://mariadb.com/kb/en/alter-table/#drop-column