将键添加到空hstore列

jan*_*anr 18 postgresql

根据postgres文档,您可以将键添加到hstore列,如下所示:

UPDATE tab SET h = h || ('c' => '3');
Run Code Online (Sandbox Code Playgroud)

但它似乎只有在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)
Run Code Online (Sandbox Code Playgroud)

更新成功,但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)
Run Code Online (Sandbox Code Playgroud)

有没有办法以原子方式将密钥添加到hstore而不先检查hstore是否为空?

Dan*_*ons 17

我认为这里的问题是你拥有的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)
Run Code Online (Sandbox Code Playgroud)

遗憾的是,我没有看到创建空hstore的hstore(array[]::varchar[])更简洁方法,但这并不意味着没有更好的方法.您可以将此功能合并到之前的hstore更新中,如下所示:

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

这样您就不需要重新创建表.我觉得相当严重.希望这可以帮助.

  • 未来可能对某人有用.我正在使用8.4并使用hstore('')而不是hstore(array [] :: varchar [])创建空的hstore (2认同)

cen*_*ntr 7

为避免这种情况,您需要确保将hstore创建为空而不是null.您可以将空hstore添加到现有表:

ALTER TABLE htest ADD h HSTORE NOT NULL DEFAULT '';
Run Code Online (Sandbox Code Playgroud)

或者您可以将现有的hstore更改为空:

ALTER TABLE htest ALTER COLUMN h SET NOT NULL;
ALTER TABLE htest ALTER COLUMN h SET DEFAULT '';
Run Code Online (Sandbox Code Playgroud)

请注意,将列设置为"NOT NULL"时,退出的值不能为null.


小智 6

怎么样:

UPDATE htest SET h = COALESCE(h, '') || ('foo'=>'bar') WHERE t='key';
Run Code Online (Sandbox Code Playgroud)


小智 5

对于 Postgres 版本> 9.1

UPDATE htest SET h = COALESCE(h, hstore('')) || hstore('foo', 'bar') WHERE t='key';
Run Code Online (Sandbox Code Playgroud)