更新查询返回列更新的否

时间:2018-02-07 10:04:55

标签: java sql postgresql prepared-statement

我正在使用java prepared语句中的readelf -x .text tmp.o查询。在此总是一次只更新一行,我需要知道任何列值是更新或列值更新。这些可能吗?如果可能的话怎么样?

2 个答案:

答案 0 :(得分:3)

这里没有任何内置功能。您可以使用可写的CTE来完成,但这不会非常有效:

使用以下测试数据:

create table test (id integer primary key, col1 text, col2 integer, col3 date);

insert into test 
values 
(1, 'foo', 42, date '2018-02-07');

以下更新将返回1,因为只有一列更改了

with updated as (
  update test 
     set col1 = 'x', 
         col2 = 42,
         col3 = date '2018-02-07'
  where id = 1
  returning *         
)
select (o.col1 is distinct from u.col1)::int 
       + (o.col2 is distinct from u.col2)::int 
       + (o.col3 is distinct from u.col3)::int as columns_changed
from test o
  join updated u on u.id = o.id;

这是有效的,因为CTE的最终select语句没有在实际表中看到update语句的结果。

如果您只需要知道 某些内容是否已更改(而不是确切的列数),您可以将语句简化为:

with updated as (
  update test 
     set col1 = 'x', 
         col2 = 42,
         col3 = date '2018-02-07'
  where id = 1
  returning *         
)
select (o is distinct from u) as was_changed
from test o
  join updated u on u.id = o.id;

第三种选择是使用hstore模块:

with updated as (
  update test 
     set col1 = 'x', 
         col2 = 42,
         col3 = date '2018-02-07'
  where id = 1
  returning *         
)
select hstore(u) - hstore(o) as modified_columns
from test o
  join updated u on u.id = o.id;

将返回:

modified_columns
----------------
"col1"=>"x"     

这意味着col1更新为值'x'

答案 1 :(得分:0)

下式给出:

t=# create table so4(i int, t text);
CREATE TABLE
t=# insert into so4 values (1,'a'),(2,'b');
INSERT 0 2

示例:

t=# with u as (update so4 u set i=3, t = 'c' 
from so4 w where u.i=1 and u.i = w.i 
returning (u.i <> w.i)::int  i, (u.t <> w.t)::int t) select i+t from u;
 ?column?
----------
        2
(1 row)

t=# with u as (update so4 u set i=3, t = 'b' 
from so4 w where u.i=2 and u.i = w.i
returning (u.i <> w.i)::int  i, (u.t <> w.t)::int t) select i+t from u;
 ?column?
----------
        1
(1 row)

t=# with u as (update so4 u set i=2, t = 'b' 
from so4 w where u.i=2 and u.i = w.i 
returning (u.i <> w.i)::int  i, (u.t <> w.t)::int t) select i+t from u;
 ?column?
----------
        0
(1 row)

基于逻辑,即true的整数值是1,所以你可以只检查旧值是否等于新值。

当没有更新行时,它将返回没有行而不是零