版本:PostgreSQL 12.4版本
方案:
CREATE TABLE table1 (
id int16 NOT NULL,
placed_count int4 NOT NULL DEFAULT 0,
picked_count int4 NOT NULL DEFAULT 0,
packed_count int4 NOT NULL DEFAULT 0,
generated_status int2 NULL GENERATED ALWAYS AS (calculate_status(placed_count, picked_count, packed_count)) STORED,
CONSTRAINT table1_pk PRIMARY KEY (id),
);
功能:
CREATE OR REPLACE FUNCTION calculate_status(
placed_count integer,
picked_count integer,
packed_count integer
)
RETURNS integer
LANGUAGE sql
IMMUTABLE STRICT
AS $function$
select
case
when placed_count <= 0 then 1 --pending
when packed_count = placed_count then 3 --packed
when picked_count = placed_count then 2 --picked
else 4 --else
end
$function$
;
generated_status生成的列在某些记录中不是最新的,并且与使用该行中找到的相同值运行函数的结果不匹配。
SELECT count(*) FROM Table1 tt
WHERE generated_status !=
calculate_status
(
tt.placed_count,
tt.picked_count,
tt.packed_count
)
会传回正数。
我通常遇到问题的行是:
| 识别码|放置_计数|拾取_计数|压缩计数|生成的状态|
| - -|- -|- -|- -|- -|
| 一个|三个|三个|三个|2个|
| 2个|四个|四个|四个|2个|
当我将这些值输入到函数中时,它们确实返回3,但在我看来,生成的列有时并没有为最后放置的计数更新而更新,或者它的值被一些并发问题/争用条件覆盖。
什么可能是错误的,这并不经常发生(~30在100 k),但我需要这个状态总是最新的,否则它会造成一些麻烦。
1条答案
按热度按时间dldeef671#
发生这种情况的唯一方法(除非有错误)是更改函数的定义。这样做不会导致重新计算预先存在的行的值。
更新:我能够复制这一点,并提交了a bug report,其中有复制器的情况下附加到它。