2012-02-16 38 views
17

據Postgres的文件,添加一個關鍵的hstore列如下:添加一鍵空hstore列

UPDATE tab SET h = h || ('c' => '3'); 

但似乎如果hstore字段不爲空,只工作。例如:

postgres=# create table htest (t text, h hstore); 
CREATE TABLE 
postgres=# insert into htest (t) VALUES ('key'); 
INSERT 0 1 
postgres=# update htest set h = h || ('foo'=>'bar') where t='key'; 
UPDATE 1 
postgres=# select * from htest; 
    t | h 
-----+--- 
key | 
(1 row) 

更新成功,但沒有更新的hstore。但是:

postgres=# update htest set h = ('foo'=>'bar') where t='key'; 
UPDATE 1 
postgres=# select * from htest; 
    t |  h  
-----+-------------- 
key | "foo"=>"bar" 
(1 row) 

postgres=# update htest set h = h || ('bar'=>'foo') where t='key'; 
UPDATE 1 
postgres=# select * from htest; 
    t |    h    
-----+---------------------------- 
key | "bar"=>"foo", "foo"=>"bar" 
(1 row) 

有沒有一種方法以原子一鍵添加到hstore沒有先檢查是否hstore是空的?

回答

16

我認爲這裏的問題是你所擁有的hstore是null,null或者某個hstore是null。

我擁有的最佳解決方案可能不是最好的解決方案,那就是使表的默認空hstore而不是允許null。那麼你的工作的例子,你想:

postgres=# create table htest (t text, h hstore default hstore(array[]::varchar[])); 
CREATE TABLE 
postgres=# insert into htest (t) values ('key'); 
INSERT 0 1 
postgres=# update htest set h = h || ('foo'=>'bar') where t='key'; 
UPDATE 1 
postgres=# select * from htest; 
    t |  h  
-----+-------------- 
key | "foo"=>"bar" 
(1 row) 

可惜我沒有看到一個更清潔的方式來創建一個空的hstore比hstore(array[]::varchar[])但是,這並不意味着沒有更好的辦法。你可以將它合併到你之前的hstore更新中,例如:

update htest set h = coalesce(h, hstore(array[]::varchar[])) || ('foo'=>'bar') where t='key'; 

這樣你就不需要重新創建表格了。儘管如此,我覺得這很公平。希望這可以幫助。

+0

謝謝!我意識到我的hstore是空的,但我不知道這與空hstore有什麼不同。 – janr 2012-02-16 20:42:49

+0

好東西,謝謝Daniel! – 2012-12-06 21:52:18

+2

未來可能對某人有幫助。我使用8.4,我創建了hstore('')而不是hstore(array [] :: varchar [])的空hstore – trex005 2013-03-07 20:11:41

6

爲了避免這種情況,您需要確保hstore創建爲空且不爲空。您可以添加一個空hstore現有表:

ALTER TABLE htest ADD h HSTORE NOT NULL DEFAULT ''; 

或者你可以改變你現有的hstore清空:

ALTER TABLE htest ALTER COLUMN h SET NOT NULL; 
ALTER TABLE htest ALTER COLUMN h SET DEFAULT ''; 

請注意,當您將列'退出值不能爲空NOT NULL'。

6

怎麼樣:

UPDATE htest SET h = COALESCE(h, '') || ('foo'=>'bar') WHERE t='key'; 
4

Postgres的版本> 9.1

UPDATE htest SET h = COALESCE(h, hstore('')) || hstore('foo', 'bar') WHERE t='key';