在 PostgreSQL 中,假设您有一个具有以下定义的表和视图:

CREATE TABLE boq_items (
    id character varying(22) NOT NULL,
    item_no character varying(50) NOT NULL,
    activity_name character varying(255) NOT NULL,
    page_no int NOT NULL,
    qty numeric(14,2) NOT NULL,
    rate numeric(14,2) NOT NULL,
    bq_amt numeric(14,2) NOT NULL
);

CREATE VIEW vw_boq_item_names AS
    SELECT activity_name FROM boq_items;

进入全屏模式 退出全屏模式

尝试使用ALTER TABLE boq_items ALTER activity_name TYPE text, ALTER activity_name SET NOT NULL;更改activity_name列的定义将返回cannot alter type of a column used by a view or rule. DETAIL: rule _RETURN on view vw_boq_item_names depends on column "activity_name"错误。如果您尝试更改表的任何列定义,PostgreSQL 将抛出相同的错误。

PostgreSQL 允许在事务](https://wiki.postgresql.org/wiki/Transactional_DDL_in_PostgreSQL:_A_Competitive_Analysis)中运行[条 DDL 语句。要解决该错误,我们需要删除视图,运行 alter 语句并重新创建视图,但将这些语句包含在事务中。

BEGIN;
  DROP VIEW vw_boq_item_names;

  ALTER TABLE boq_items
    ALTER activity_name TYPE text,
    ALTER activity_name SET NOT NULL;

  CREATE VIEW vw_boq_item_names AS
    SELECT activity_name FROM boq_items;

COMMIT;

进入全屏模式 退出全屏模式

如果您使用的是FluentMigrator数据库迁移框架,请排除BEGIN;COMMIT;语句 - 否则迁移将失败并出现错误。

public override void Up()
{
  var sql = "DROP VIEW vw_boq_item_names;"  +

            "ALTER TABLE boq_items " +
              "ALTER activity_name TYPE text, " +
              "ALTER activity_name SET NOT NULL;" +

            "CREATE VIEW vw_boq_item_names AS " +
                "SELECT activity_name FROM boq_items;"

    Execute.Sql(sql);
}

进入全屏模式 退出全屏模式

在表具有大量依赖项或对象具有级联依赖项的情况下,解决方案将创建两个函数 - 一个用于保存依赖项,另一个用于恢复这些依赖项。这些函数中的每一个都需要模式和模式中具有依赖关系的对象的参数。在更改表和列定义之前,调用函数保存和删除依赖关系,进行定义更改,最后调用函数恢复依赖关系。

select util.deps_save_and_drop_dependencies('mdm', 'global_item_master_swap');

alter table mdm.global_item_master_swap
alter column prod_id type varchar(128),
alter column prod_nme type varchar(512);

select util.deps_restore_dependencies('mdm', 'global_item_master_swap');

进入全屏模式 退出全屏模式

不再担心 PostgreSQL 中的表和视图依赖关系详细说明了这些函数的工作原理。该帖子包含指向sql fiddle和最新gist的链接。

我希望这对在更新表列定义时在 PostgreSQL 中遇到cannot alter type of a column used by a view or rule错误的任何人有所帮助。

Logo

PostgreSQL社区为您提供最前沿的新闻资讯和知识内容

更多推荐