插入表时如何访问值?

我正在尝试编写Java sql查询,简化后的表将是对(name,version)具有唯一约束的table(name,version)。

我正在尝试使用条件语句在数据库中插入一行。这意味着,当存在具有相同名称的条目时,应插入具有相同名称的行,并且其版本增加1。

我尝试了以下方法:

INSERT INTO table(name,version) 
VALUES(?,CASE WHEN EXISTS(SELECT name from table where name=?)
THEN (SELECT MAX(version) FROM table WHERE name = ?) +1
ELSE 1 END)

值由用户发送。

我的问题是,如何访问值中的“名称”,以便可以进行比较?

qq394496014 回答:插入表时如何访问值?

如果您想将其写为一个查询:

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)

这种方法非常简单,易于阅读和实施,但是由于需要进行大量查询,因此效果不佳。

  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

大家都在问