【问题标题】:PostgreSQL v7.4 ALTER TABLE to change columnPostgreSQL v7.4 ALTER TABLE 更改列
【发布时间】:2010-12-21 18:38:15
【问题描述】:

我需要更改 PostgreSQL v7.4 数据库中表中 CHAR 列的长度。此版本不支持使用 ALTER TABLE 语句直接更改列类型或大小的功能。因此,例如,直接将列从 CHAR(10) 更改为 CHAR(20) 是不可能的(是的,我知道,“使用 varchars”,但在我目前的情况下这不是一个选项)。有人对如何最好地完成此任务有任何建议/技巧吗?我最初的想法:

-- 将表的数据保存在一个新的“保存”表中。 CREATE TABLE save_data AS SELECT * FROM table_to_change;

-- 从要更改的第一列中删除列。 ALTER TABLE table_to_change DROP column_name1; -- 从需要修改的第一列开始的每一列 ALTER TABLE table_to_change DROP column_name2; ...

-- 重新添加列,使用 CHAR 列的新大小 ALTER TABLE table_to_change ADD column_name1 CHAR(new_size); -- 对于上面删除的每一列 ALTER TABLE table_to_change ADD column_name2...

-- 从“保存”表中复制数据 更新 table_to_change SET column_name1=save_data.column_name1, -- 对于上面删除/读取的每一列 column_name2=save_date.column_name2, ... FROM 保存数据 WHERE table_to_change.primary_key=save_data.primay_key;

呸!希望有更好的方法吗?任何建议表示赞赏。谢谢!

【问题讨论】:

    标签: postgresql alter-table


    【解决方案1】:

    不是 PostgreSQL,但在 Oracle 中,我通过以下方式更改了列的类型:

    1. 添加具有临时名称(即:TMP_COL)和新数据类型(即:CHAR(20)的新列)
    2. 运行更新查询:UPDATE TBL SET TMP_COL = OLD_COL;
    3. 删除OLD_COL
    4. TMP_COL 重命名为OLD_COL

    【讨论】:

    • 另一种好方法,尽管它会导致重新定位表模式中的列位置。我需要检查该表是否曾经接收到 ASCII 文件加载,例如列位置相关的位置。
    【解决方案2】:

    我会使用 COPY 将表格内容转储到平面文件中,删除表格,使用正确的列设置重新创建它,然后重新加载(再次使用 COPY)。

    http://www.postgresql.org/docs/7.4/static/sql-copy.html

    在执行此操作时有停机时间是否可以接受?显然,我刚刚描述的需要使表在一段时间内无法使用,多长时间取决于您正在使用的数据大小和硬件。

    编辑: 但是 COPY 比 INSERT 和 UPDATE 快很多。根据文档,您可以使用 BINARY 模式使其更快。 BINARY 使其与其他 PGSQL 安装的兼容性降低,但您不会关心这一点,因为您只想将数据加载到您从中转储数据的同一实例。

    【讨论】:

    • 我想过做一个这样的删除/创建表,但我希望不必删除它,因为我需要重新授予所有权限。这个操作需要在大约 50 台服务器上进行,每台服务器都有自己的数据库、用户等,因此希望制作一个可以在每台服务器上运行的 SQL 更新脚本。我想我可以保存表的 pg_class.relacl 值并在删除/添加后重置它以获取权限。
    • 是的,这听起来确实很痛苦。您还可以使用 pg_dump 导出表的设置。有了它,您应该能够编写出所有需要应用于该表的命令,然后在重新创建表后重新运行它们。不过,您的临时表解决方案最终可能会更简单。
    • FWIW,我的工作是开发一个维护数据库表的系统,我们在这种情况下使用的方法是你描述的和我描述的方法。 COPY(或您的 RDBMS 使用的任何批量加载程序)速度更快,但临时表的侵入性较小。
    【解决方案3】:

    解决问题的最佳方法是将 pg 升级到不那么陈旧的东西 :)

    说真的。 7.4 很快就会从“支持的版本”中删除,所以我不会等待它在生产中的 7.4 中发生。

    【讨论】:

    • 叹息...我知道,但目前还不是一个选项 :( 我记得在 80 年代后期使用更古老的 Informix-SE 支持 ALTER TABLE 可以更改列类型/大小地方。遗憾的是 PostgreSQL 的人不能在 2003 年左右或 v7.4 中做同样的事情。哦,好吧。
    • 我相信你可以拿回你的钱。
    • 是的,我知道,它是免费的,而且我喜欢 PostgreSQL。但是,在 v7+ 版本中似乎缺少 DDL 的基本功能。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-11-18
    • 1970-01-01
    • 2012-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多