52

我想在 PostgreSQL 9.1.5 中更改枚举类型中项目的名称。

这是该类型的创建 stmt:

CREATE TYPE import_action AS ENUM
('Ignored',
'Inserted',
'Updated',
'Task created');

我只想将“创建的任务”更改为“已中止”。从文档看来,以下内容应该有效:

ALTER TYPE import_action
RENAME ATTRIBUTE "Task created" TO "Aborted"; 

但是,我收到一条消息:

********** Error **********

ERROR: relation "import_action" does not exist
SQL state: 42P01

但是,它显然确实存在。

该类型当前被多个表使用。

我正在认为一定没有办法做到这一点。我已经尝试了 pgAdminIII 中类型的对话框,但是我看不到在那里重命名它。(所以,要么强烈暗示我做不到,要么 - 我希望 - 一个小的疏忽是创建该对话框的开发人员)

如果我不能在一个声明中做到这一点?那我需要做什么?我是否必须编写脚本来添加项目,将所有记录更新为新值,然后删除旧项目?这甚至会起作用吗?

看起来这应该是一件简单的事情。据我了解,记录只是存储对类型和项目的引用。我认为它们实际上并没有存储我给它的文本值。但是,也许我在这里也错了。

4

4 回答 4

96

在 PostgreSQL 版本 10 中,重命名枚举标签的功能已添加ALTER TYPE语法的一部分:

ALTER TYPE name RENAME VALUE 'existing_enum_value' TO 'new_enum_value'
于 2017-08-01T18:02:58.213 回答
43

更新:对于 PostgreSQL 版本 10 或更高版本,请参阅投票最多的答案。

枚举值的名称称为标签,属性完全不同。

不幸的是,更改枚举标签并不简单,您必须使用系统目录: http ://www.postgresql.org/docs/9.1/static/catalog-pg-enum.html

UPDATE pg_enum SET enumlabel = 'Aborted' 
WHERE enumlabel = 'Task created' AND enumtypid = (
  SELECT oid FROM pg_type WHERE typname = 'import_action'
)
于 2012-09-27T19:04:39.757 回答
13

接受的答案中的查询不考虑架构名称。这是一个更安全(更简单)的,基于http://tech.valgog.com/2010/08/alter-enum-in-postgresql.html

UPDATE pg_catalog.pg_enum
SET enumlabel = 'NEW_LABEL'
WHERE enumtypid = 'SCHEMA_NAME.ENUM_NAME'::regtype::oid AND enumlabel = 'OLD_LABEL'
RETURNING enumlabel;

请注意,这需要“rolcatupdate”(直接更新目录)权限——即使是超级用户也是不够的。

从 PostgreSQL 9.3 开始,似乎直接更新目录仍然是唯一的方法。

于 2013-09-13T14:46:08.140 回答
7

类型、属性和值之间存在差异。你可以像这样创建一个枚举。

CREATE TYPE import_action AS ENUM
('Ignored',
'Inserted',
'Updated',
'Task created');

完成后您可以向枚举添加值。

ALTER TYPE import_action 
ADD VALUE 'Aborted';

但是语法图没有显示任何对删除或重命名value的支持。您正在查看的语法是重命名属性的语法,而不是值。

尽管这种设计可能令人惊讶,但它也是经过深思熟虑的。来自pgsql-hackers 邮件列表

如果您需要修改使用的值或想知道整数是什么,请改用查找表。枚举对您来说是错误的抽象。

于 2012-09-27T19:04:24.140 回答