我正在使用java prepared语句中的readelf -x .text tmp.o
查询。在此总是一次只更新一行,我需要知道任何列值是更新或列值更新。这些可能吗?如果可能的话怎么样?
答案 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,所以你可以只检查旧值是否等于新值。
当没有更新行时,它将返回没有行而不是零