一次将所有表中的列类型从 varchar 更改为 text

Zie*_*emo 6 postgresql alter-table

我正在使用 Postgres。我想将列名称为“描述”的所有表中的列类型从 varchar(255) 更改为文本。

如果有人知道我会很高兴得到你的帮助。

a_h*_*ame 8

我猜您不想手动运行所有必要的ALTER TABLE语句。

您可以使用以下语句来生成所需的ALTER TABLE语句:

select 'alter table '||table_schema||'.'||table_name||' alter column '||column_name||' type text;'
from information_schema.columns
where table_schema = 'public'
  and column_name = 'description'
  and data_type = 'character varying'
  and character_maximum_length = 255;
Run Code Online (Sandbox Code Playgroud)

'public'如果您的表不在架构中,请替换为您的public架构。

运行上面的语句,将输出假脱机到一个文本文件中,然后运行生成的脚本。

像这样的东西:

psql (9.3.4)
输入“帮助”以获得帮助。
postgres=> \t
只显示元组。
postgres=> \o alter.sql
postgres=> 选择'更改表'||table_schema||'。'||table_name||' 更改列“||column_name||” 输入文字;'
postgres-> 来自 information_schema.columns
postgres-> where table_schema = 'public'
postgres-> 和 column_name = 'description'
postgres-> and data_type = '字符变化'
postgres-> 和 character_maximum_length = 255;
postgres=> \i alter.sql


Erw*_*ter 5

您可以使用DO语句来运行单个动态命令:

DO
$do$
BEGIN

RAISE NOTICE '%', (
-- EXECUTE (
   SELECT string_agg(format('ALTER TABLE %s ALTER COLUMN %I TYPE text'
                           , a.attrelid::regclass, a.attname), E';\n')
   FROM   pg_attribute a
   JOIN   pg_class     c ON c.oid = a.attrelid
   JOIN   pg_namespace n ON n.oid = c.relnamespace
   WHERE  a.attname = 'description'
   AND    a.atttypid = 'varchar'::regtype
   AND    NOT a.attisdropped                      -- no dropped columns
   AND    a.attnum > 0                            -- no system columns (redundant check)
   AND    format_type(a.atttypid, a.atttypmod) = 'character varying(255)'
   AND    n.nspname NOT LIKE ALL ('{pg_%, information_schema}'::text[])
   );

END
$do$;
Run Code Online (Sandbox Code Playgroud)

由于该命令具有潜在危险,因此我对其进行了评论EXECUTE并在RAISE NOTICE那里放置了一个。确认命令无误后,切换注释字符--,实际执行DDL命令。

上的手册format_type()

这会更改所有列的类型description varchar(255),但系统目录、临时表(均以“pg_”开头)和信息模式中的列除外。我从系统目录构建命令。@a_horse 演示了另一个使用信息模式的好选择

在您的特定情况下,每个表只能有列。如果可以有多个,则在每个表的单个 ALTER TABLE语句中执行所有类型更改会便宜得多。形式命令:

ALTER TABLE foo
    ALTER COLUMN col1 TYPE text
  , ALTER COLUMN col2 TYPE text
  , ALTER COLUMN col3 TYPE text;
Run Code Online (Sandbox Code Playgroud)

此相关答案中的更多详细信息:
由于 plpgsql 中的字符串周围有不需要的括号,动态更新失败