根据Postgres文档,您可以按如下方式向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?
我认为这里的问题是你拥有的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(array [] :: varchar [])创建一个空的hstore更清洁的方法,但这并不意味着没有更好的方法。您可以从之前将其纳入您的hstore更新:
update htest set h = coalesce(h,hstore(array[]::varchar[])) || ('foo'=>'bar') where t='key';
这样你就不需要重新创建表。我发现相当毛骨悚然。希望这可以帮助。