Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/341.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 避免在同一表中插入重复项_Java_Sql_Sqlite_Duplicates_Upsert - Fatal编程技术网

Java 避免在同一表中插入重复项

Java 避免在同一表中插入重复项,java,sql,sqlite,duplicates,upsert,Java,Sql,Sqlite,Duplicates,Upsert,我有一个JAVA程序,它在数据库中创建一个表,然后在这个表中插入行。 该表创建如下: String sql = "CREATE TABLE IF NOT EXISTS weather (\n" + " city string,\n" + " temp real,\n" + " feels_like real,\n"

我有一个JAVA程序,它在数据库中创建一个表,然后在这个表中插入行。 该表创建如下:

        String sql = "CREATE TABLE IF NOT EXISTS weather (\n"
            + " city string,\n"
            + " temp real,\n"
            + " feels_like real,\n"
            + " temp_min real,\n"
            + " temp_max real,\n"
            + " pressure integer,\n"
            + " humidity integer\n"
            + ");";
添加行时,我不希望名为“city”的字段有重复的行。 因此,例如,如果我已经有了伦敦的数据,我不想再添加它,即使它的所有数据可能已经改变了。我只想在桌子上放一次

我有以下要插入的查询:

        String sql = "INSERT INTO weather VALUES(?,?,?,?,?,?,?);";
我想修改它,这样我就不会插入重复的城市。 有人能帮我吗?谢谢

您现在可以使用。这要求您在
city
上具有唯一的索引/约束,但它已定义为主键。检查

insert into weather ( . . . )
    values ( . . . )
    on conflict (city) ignore;
SQLite还允许这种速记:

insert or ignore into weather ( . . . )
    values ( . . . );

在“有效的标准SQL”中没有办法做到这一点*

但是,每个单独的DB引擎通常都有一些实现这一目标的方法

这个概念被称为合并或升级-这些是你可以在网上搜索的术语。例如,只需搜索“如何升级postgres”。之所以称为upsert,是因为更一般的应用是:如果我插入的值的某个子集在DB中还不存在,请插入一个包含此数据的新行。否则,请为该子集找到具有相同值的行,然后用它更新所有其他值。例如:“找到ID为12345的学生,然后将其名称更改为‘Joe Bloggs’。如果没有包含该名称的行,则将其更改为”

将所有值都设置为“关键值”,然后将“插入,如果已经存在则忽略”减少为标准的UPSERT

在psql中,您可以在冲突上执行操作。搜索“mysql upsert”会让你看到博客文章,这些文章根据你的具体需要提供不同的策略,从使用
INSERT IGNORE
(我建议不要这样做,这会忽略任何和所有错误,而不是只忽略“已经在这里”错误)、重复密钥更新(更好的主意,这一点)或使用REPLACE

您在这里使用的任何db引擎都可以找到类似的博客文章


*)未定义为“根据SQL标准的某些版本”,但定义为:“适用于大多数现有DB引擎”。

如果您使用的SQLite版本为3.24.0+,并且对列
city
有唯一的约束,如果发生唯一约束冲突,您可以使用该选项执行
无操作
更新
表格。

在这种情况下:

String sql = 
    "INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
    "ON CONFLICT DO NOTHING";
如果您试图插入一个包含现有
城市的行,则该语句将不会出错。

但是,如果新行包含其他列的最新数据,并且希望更新该行,则可以执行以下操作:

String sql = 
    "INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
    "ON CONFLICT(city) DO UPDATE SET "
    "temp = excluded.temp, " + 
    "feels_like = excluded.feels_like, " + 
    "temp_min = excluded.temp_min, " + 
    "temp_max = excluded.temp_max, " + 
    "pressure = excluded.pressure, " + 
    "humidity = excluded.humidity";
其他6列将被您提供的新值覆盖

如果没有为
city
定义唯一约束,并且您不想或无法定义一个约束,则可以避免在
不存在的情况下插入同一城市两次,如下所示:

String sql = 
    "INSERT INTO weather SELECT ?,?,?,?,?,?,? " +
    "WHERE NOT EXISTS (SELECT 1 FROM weather WHERE city = ?);

在这种情况下,您必须将Java代码作为附加的第8个参数再次传递
city
的值。

我尝试了这两个参数,但它们似乎都不起作用。他们不断添加同一城市的行。您使用的是哪个版本的SQLite?自SQLite版本3.24以来,就一直支持这一点。否决票是相当粗鲁的,因为这个答案引用了说明代码工作的SQLite文档。@GordenLinoff这是PSQLese,除非您有一个正确的唯一索引或PK定义,否则根本不起作用。它也不适用于mssql、mysql和许多其他DB引擎。。。。哦,这个问题的标签(现在?)包括sqlite。没关系,继续:)@GordonLinoff这是3.32版。为什么不把城市定义为独一无二的呢?我尝试了你所有的选择,但都不起作用。他们不断添加同一个城市。@WillWost我注意到你编辑了你的问题并从城市中删除了主键。为什么?如果city是主键,那么前两个查询应该可以工作。最后一个在任何情况下都有效。发布您实际执行的Java代码。我编辑它是因为我不希望城市成为主键。这只是我做的一个测试,但我忘了删除它。我现在通过创建一个新的数据库重试,您向我提出的第一个查询可以工作。这正常吗?我为城市添加了两个约束:notnull和UNIQUE。@WillWost当然这是正常的。这就是它的工作原理。如果存在唯一的约束冲突,
ON CONFLICT DO NOTHING
子句将使语句不执行任何操作。我还有另一个问题,请回答。在第二个查询中,排除的是什么?我不明白。非常感谢你!