Postgresql 向空的hstore列添加键

Postgresql 向空的hstore列添加键,postgresql,Postgresql,根据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 hte

根据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';

这样,您就不需要重新创建表。不过我觉得这相当恶心。希望这有帮助。

为了避免这种情况,您需要确保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”时,退出值不能为null

那么:

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

对于Postgres版本>9.1

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

谢谢我意识到我的hstore是空的,但我不知道这与空的hstore有什么不同。这可能对将来的人有帮助。我使用的是8.4,我使用hstore(“”)而不是hstore(数组[]:::varchar[])创建空的hstore