2016-02-04 77 views
1

我最近一直在优化Postgres的一些表格,尽可能将更复杂的数据类型转换为更简单的数据类型。除了每一个的情况下,到目前为止,这一直是相当简单的,例如:更改Postgres整数列以键入布尔值

ALTER TABLE products ALTER COLUMN price TYPE integer USING price::integer;

对于将文本转换成自定义枚举数据类型,这也已经足够简单。我只写了将文本转换为一个枚举函数PLPGSQL,然后转换列像这样:

ALTER TABLE products ALTER COLUMN color TYPE color_enum USING text_to_color_enum(color);

此语法虽然失败了,在那里我有一个整数转换为布尔案件。这些都失败:

ALTER TABLE products ALTER return_policy TYPE boolean USING return_policy > 0;

ALTER TABLE products ALTER return_policy TYPE boolean USING bool(return_policy);

ALTER TABLE products ALTER COLUMN return_policy TYPE boolean USING bool(return_policy);

ALTER TABLE products ALTER COLUMN return_policy TYPE boolean USING CASE WHEN return_policy <> 0 THEN TRUE ELSE FALSE END;

错误消息总是相同的:

ERROR: operator does not exist: boolean = integer

HINT: No operator matches the given name and argument type(s). You might need to add explicit type casts.

该列中没有空值。所有值都是零或正值。 SELECT pg_typeof(return_policy) FROM products LIMIT 1;返回integer。创建一个从整数到布尔型的自定义转换失败,因为显然已经存在。 Postgres 9.4和9.5也会发生同样的情况。我在这里做错了什么?

+0

看到这个http://stackoverflow.com/questions/1740303/postgres-alter-column-integer-to-boolean – monteirobrena

+0

是的,我读了该页,并尝试这些方法。他们没有为我工作,我仍然像以前一样得到相同的错误信息。 – virnovus

回答

2

验证列是否为约束条件,如果是,则需要在更改类型之前移除约束条件。

ALTER TABLE products ALTER COLUMN price DROP DEFAULT; 
ALTER TABLE products ALTER price TYPE bool USING CASE WHEN price = 0 THEN FALSE ELSE TRUE END; 
ALTER TABLE products ALTER COLUMN price SET DEFAULT FALSE; 
+0

最初有一个约束,它给了我一个错误消息,指出有一个约束。我删除了约束,现在我得到当前的错误信息。做'\ d +产品'在'return_policy'列没有显示修饰符。 – virnovus

+0

@virnovus你在这个列中有一个空值吗? – monteirobrena

+0

不,我已经检查过了,就像我说的那样,该列中没有空值。 – virnovus

1

我的一个部分索引有一个条件WHERE return_policy = 30。 (这个数字意味着退货政策的天数,但由于我们提供的一切都不是退货政策或30天退货政策,因此它不再是合理的。)删除索引允许我的原始SQL代码正确运行。