2016-02-04 79 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代碼正確運行。