PostgreSQL 教程: DROP COLUMN 删除表中的列

九月 12, 2023

摘要:本教程向您展示如何在ALTER TABLE语句中使用DROP COLUMN子句来删除表中的一列或多列。

PostgreSQL DROP COLUMN

PostgreSQL DROP COLUMN 子句简介

要删除表中的列,请在ALTER TABLE语句中使用DROP COLUMN子句,如下所示:

ALTER TABLE table_name 
DROP COLUMN column_name;

当您从表中删除列时,PostgreSQL 将自动删除涉及已删除列的所有索引和约束。

如果要删除的列在其他数据库对象(例如视图触发器存储过程等)中使用,则无法删除该列,因为其他对象依赖于它。在这种情况下,您需要向DROP COLUMN子句添加CASCADE选项以删除列及其所有依赖对象:

ALTER TABLE table_name 
DROP COLUMN column_name CASCADE;

如果删除不存在的列,PostgreSQL 将发出错误。要仅删除存在的列,您可以添加IF EXISTS选项,如下:

ALTER TABLE table_name 
DROP COLUMN IF EXISTS column_name;

在这种形式中,如果删除不存在的列,PostgreSQL 将发出通知而不是错误。

如果要在单个命令中删除表的多个列,可以使用多个DROP COLUMN子句,如下所示:

ALTER TABLE table_name
DROP COLUMN column_name1,
DROP COLUMN column_name2,
...;

请注意,您需要在每个DROP COLUMN子句后面添加一个逗号 (,)。

如果表只有一列,则可以使用ALTER TABLE DROP COLUMN语句删除它。那么该表就没有列了。这在 PostgreSQL 中是可能的,但根据 SQL 标准是不可能的。

让我们看一些示例来了解ALTER TABLE DROP COLUMN语句是如何工作的。

PostgreSQL DROP COLUMN 示例

我们将创建三个表:bookscategoriespublishers,用于演示。

PostgreSQL DROP COLUMN Example Diagram

在此图中,每本书只有一个出版商,每个出版商可以出版多本书。每本书都被分配到一个类别,每个类别可以有很多本书。

以下语句创建三个表:

CREATE TABLE publishers (
    publisher_id serial PRIMARY KEY,
    name VARCHAR NOT NULL
);

CREATE TABLE categories (
    category_id serial PRIMARY KEY,
    name VARCHAR NOT NULL
);

CREATE TABLE books (
    book_id serial PRIMARY KEY,
    title VARCHAR NOT NULL,
    isbn VARCHAR NOT NULL,
    published_date DATE NOT NULL,
    description VARCHAR,
    category_id INT NOT NULL,
    publisher_id INT NOT NULL,
    FOREIGN KEY (publisher_id) 
       REFERENCES publishers (publisher_id),
    FOREIGN KEY (category_id) 
       REFERENCES categories (category_id)
);

另外,我们基于bookspublishers创建一个视图,如下:

CREATE VIEW book_info 
AS SELECT
    book_id,
    title,
    isbn,
    published_date,
    name
FROM
    books b
INNER JOIN publishers 
    USING(publisher_id)
ORDER BY title;

以下语句使用ALTER TABLE DROP COLUMN语句从books表中删除category_id列:

ALTER TABLE books 
DROP COLUMN category_id;

让我们展示一下books表的结构

test=# \d books;
                                     Table "public.books"
     Column     |       Type        |                        Modifiers
----------------+-------------------+---------------------------------------------------------
 book_id        | integer           | not null default nextval('books_book_id_seq'::regclass)
 title          | character varying | not null
 isbn           | character varying | not null
 published_date | date              | not null
 description    | character varying |
 publisher_id   | integer           | not null
Indexes:
    "books_pkey" PRIMARY KEY, btree (book_id)
Foreign-key constraints:
    "books_publisher_id_fkey" FOREIGN KEY (publisher_id) REFERENCES publishers(publisher_id)

从输出中可以看到,该语句不仅删除了category_id列,还删除了涉及category_id列的外键约束

以下语句尝试删除publisher_id列:

ALTER TABLE books 
DROP COLUMN publisher_id;

PostgreSQL 发出以下错误:

ERROR:  cannot drop table books column publisher_id because other objects depend on it
DETAIL:  view book_info depends on table books column publisher_id
HINT:  Use DROP ... CASCADE to drop the dependent objects too.

它指出book_info视图正在使用books表的publisher_id列。您需要使用CASCADE选项来删除publisher_id列和book_info视图,如以下语句所示:

ALTER TABLE books 
DROP COLUMN publisher_id CASCADE;

该语句输出了以下通知,这也是我们所期望的。

NOTICE:  drop cascades to view book_info

要使用单个语句删除isbndescription列,请添加多个DROP COLUMN子句,如下所示:

ALTER TABLE books 
  DROP COLUMN isbn,
  DROP COLUMN description;

它按预期工作。

在本教程中,您学习了如何在ALTER TABLE语句中使用DROP COLUMN子句从表中删除一列或多列。