接下来的问题是,我可以根据特定列(此处为business_uuid)的值自动递增(verification_number),以便verify_number根据business_uuid自己的最大数量的verify_number递增一(1)吗? / p>
数据库如下所示: 表:验证
verification_id = integer, sequence (Primary Key)
business_uuid = text
verification_number = integer
verify_id是此表中的主键,我希望verify_number遵循它自己的自动增量,具体取决于它仅为business_uuid过滤的最高值。
business_uuid是每个商家的唯一标识符。
有可能吗?
答案 0 :(得分:0)
目前尚不清楚您是否希望将verification_number
保存到表中,但可以在查询时创建它:
select verification_id, business_uuid,
row_number() over(
partition by business_uuid
order by verification_id
) as verification_number
from verification
上述方法存在的问题是,如果删除行,verification_number
会发生变化
答案 1 :(得分:0)
我认为这是一个糟糕的设计,但如果你真的想要,你可以按如下方式实现:
创建一个唯一约束:
ALTER TABLE verification
ADD CONSTRAINT verification_uuid_nr_unique
UNIQUE (business_uuid, verification_number);
由此创建的索引也将使以下触发功能更快。
创建BEFORE
触发器以修改verification_number
:
CREATE OR REPLACE FUNCTION veritrig() RETURNS trigger
LANGUAGE plpgsql AS
$$BEGIN
SELECT COALESCE(max(verification_number)+1, 1) INTO NEW.verification_number
FROM verification
WHERE business_uuid = NEW.business_uuid;
RETURN NEW;
END;$$;
CREATE TRIGGER veritrig
BEFORE INSERT OR UPDATE ON verification FOR EACH ROW
EXECUTE PROCEDURE veritrig();
插入如下的新值:
INSERT INTO verification (business_uuid) VALUES ('42');
然后verification_number
将根据您的需要设置。
然而,并发性存在问题。
如果多个会话尝试同时插入或更新表,您将收到如下错误:
ERROR: duplicate key value violates unique constraint "verification_uuid_nr_unique"
DETAIL: Key (business_uuid, verification_number)=(43, 1) already exists.
这是因为并发修改中的SELECT
语句只会看到当前(已提交的)表内容,并可能错误地尝试为verification_number
插入相同的business_uuid
。
没有办法避免锁定表格。但是如果你收到这样的错误,你可以简单地重试交易,并且可能会在下次有效。
答案 2 :(得分:0)
CREATE OR REPLACE FUNCTION public.creaid(
IN key_field text,
IN table_mane text,
OUT id integer)
RETURNS integer AS
$BODY$
DECLARE maxid INT;
BEGIN
EXECUTE 'SELECT max('||key_field||') FROM '||table_name INTO maxid;
IF maxid IS NULL THEN
id = 1;
ELSE
id = maxid + 1;
END IF;
END;
$BODY$
LANGUAGE plpgsql VOLATILE
COST 100;
然后,您可以将该函数作为数据库每个表的每个键值的默认值调用,如下所示:
DEFAULT creaid('key_field'::text, 'table_name'::text)