如果您想将其写为一个查询:
INSERT INTO table (name,version)
SELECT ?,COLAESCE(MAX(t2.version) + 1,1)
FROM table t2
WHERE t2.name = ?;
也就是说,这很危险。两个线程可以“同时”执行此查询,并可能创建相同的版本号。您可以通过在(name,version)
上添加唯一的索引/约束来防止这种情况的发生。
使用唯一的索引/约束,如果发生冲突,更新之一将失败。
,
插入之前,您应该先获得名称。在您的情况下,如果出现问题,那么您将如何知道它,以便在插入查询之前获得名称。
不确定,但您可以尝试以下操作:
declare int version;
if exists(SELECT name from table where name=?)
then
version = SELECT MAX(version) FROM table WHERE name = ?
version += 1
else
version = 1
end
致谢。
,
我至少看到两种方法:
1.对于每对名称和版本,您首先要查询最大版本:
SELECT MAX(VERSION) as MAX FROM <table> WHERE NAME = <name>
然后使用相应的插入查询插入结果+ 1:
INSERT INTO <table>(NAME,VERSION) VALUES (<name>,result+1)
这种方法非常简单,易于阅读和实施,但是由于需要进行大量查询,因此效果不佳。
-
您可以单独使用sql并通过sql分析和窗口函数来实现此目标,例如:
SELECT NAME,ROW_NUMBER() over (partition BY NAME ORDER BY NAME) as VERSION FROM<table>
然后您可以使用CREATE TABLE as SELECT...
将查询结果保存为表格
(这里的假设是第一个版本是1,如果不是,则可以稍微修改查询)。即使对于大型数据集,此解决方案也将非常有效。
,
这实际上是一个错误的计划,您可能正在更改用户指定的数据。那可能不是想要的,也许他们不是在尝试创建新版本,而是只是不知道想要的版本已经存在。但是,您可以创建一个Java调用的函数,不仅插入请求的版本,或者如果请求的版本已经存在,则插入max + 1。此外,它返回插入的实际值。
-- create table
create table nv( name text,version integer,constraint nv_uk unique (name,version)
);
-- function to create version or 1+max if requested exists
create or replace function new_version
( name_in text,version_in integer
)
returns record
language plpgsql strict
as $$
declare
violated_constraint text;
return_name_version record;
begin
insert into nv(name,version)
values (name_in,version_in)
returning (name,version) into return_name_version;
return return_name_version;
exception
when unique_violation
then
GET STACKED DIAGNOSTICS violated_constraint = CONSTRAINT_NAME;
if violated_constraint like '%nv\_uk%'
then
insert into nv(name,version)
select name_in,1+max(version)
from nv
where name = name_in
group by name_in
returning (name,version) into return_name_version;
return return_name_version;
end if;
end;
$$;
-- create some data
insert into nv(name,version)
select 'n1',gn
from generate_series( 1,3) gn ;
-- test insert existing
select new_version('n2',1);
select new_version('n1',1);
select *
from nv
order by name,version;
本文链接:https://www.f2er.com/3138866.html