避免在 INSERT INTO 中出现重复 table
Avoid duplicates in INSERT INTO in the same table
我在 JAVA 中有一个程序,它在数据库中创建一个 table,然后我在这个 table 中插入行。
table 创建如下:
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”的字段出现重复项。
因此,例如,如果我已经拥有伦敦及其数据,我不想再次添加它,即使它的所有数据可能都已更改。我只想在我的 table.
中拥有它一次
我有这个插入查询:
String sql = "INSERT INTO weather VALUES(?,?,?,?,?,?,?);";
我想对其进行修改,以免插入重复的城市。
谁能帮帮我吗?谢谢!
您现在可以使用 on conflict
。这要求您在 city
上有一个唯一的 index/constraint,但它已被定义为主键。检查。
insert into weather ( . . . )
values ( . . . )
on conflict (city) ignore;
SQLite 也允许 shorthand:
insert or ignore into weather ( . . . )
values ( . . . );
在 'effectively standard SQL'*.
中无法执行此操作
但是,每个单独的数据库引擎通常都有一些实现此目标的方法。
概念 称为合并或更新插入 - 您可以在网上搜索这些术语。例如,只需搜索 'how to postgres upsert'。之所以称为 upsert,是因为更一般的应用是:如果我要插入的值的某些子集在数据库中尚不存在,则使用该数据插入一个新行。否则,找到该子集具有相同值的行,然后用它更新所有其他值。例如:“找到 ID 为 12345 的学生,然后将姓名更改为 'Joe Bloggs'。如果没有行,则创建它”。
将所有值设为 'the key' 并且您已将 'insert, ignore if it is already there' 缩减为标准 UPSERT。
在 psql 中,您可以执行 ON CONFLICT。搜索 'mysql upsert' 可以让您找到根据您的具体需求提供不同策略的博客文章,使用 INSERT IGNORE
(我建议不要这样做,这会忽略所有错误,而只忽略 'already in here' 仅错误),在重复密钥更新时(更好的主意,这个),或使用替换。
对于您在此处使用的任何数据库引擎,都可以找到类似的博文。
*) 未定义为 'as per some version of the SQL standard',而是定义为:'works in the majority of existing DB engines'.
如果你使用的SQLite版本是3.24.0+并且city
列有唯一约束,你可以使用upsert
如果发生 唯一约束违规 ,这使您可以选择执行 NOTHING
或 UPDATE
table。
在这种情况下:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT DO NOTHING";
如果您尝试插入具有现有 city
的行,该语句将失败且不会出现错误。
但是如果新行包含其他列的最新数据并且您希望更新该行,您可以这样做:
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
定义唯一约束并且您不想或不能定义一个,那么您可以避免使用 NOT EXISTS
插入同一个城市两次,例如这个:
String sql =
"INSERT INTO weather SELECT ?,?,?,?,?,?,? " +
"WHERE NOT EXISTS (SELECT 1 FROM weather WHERE city = ?);
在这种情况下,您必须将 Java 代码作为附加的第 8 个参数再次传递给 city
的值。
我在 JAVA 中有一个程序,它在数据库中创建一个 table,然后我在这个 table 中插入行。 table 创建如下:
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”的字段出现重复项。 因此,例如,如果我已经拥有伦敦及其数据,我不想再次添加它,即使它的所有数据可能都已更改。我只想在我的 table.
中拥有它一次我有这个插入查询:
String sql = "INSERT INTO weather VALUES(?,?,?,?,?,?,?);";
我想对其进行修改,以免插入重复的城市。 谁能帮帮我吗?谢谢!
您现在可以使用 on conflict
。这要求您在 city
上有一个唯一的 index/constraint,但它已被定义为主键。检查。
insert into weather ( . . . )
values ( . . . )
on conflict (city) ignore;
SQLite 也允许 shorthand:
insert or ignore into weather ( . . . )
values ( . . . );
在 'effectively standard SQL'*.
中无法执行此操作但是,每个单独的数据库引擎通常都有一些实现此目标的方法。
概念 称为合并或更新插入 - 您可以在网上搜索这些术语。例如,只需搜索 'how to postgres upsert'。之所以称为 upsert,是因为更一般的应用是:如果我要插入的值的某些子集在数据库中尚不存在,则使用该数据插入一个新行。否则,找到该子集具有相同值的行,然后用它更新所有其他值。例如:“找到 ID 为 12345 的学生,然后将姓名更改为 'Joe Bloggs'。如果没有行,则创建它”。
将所有值设为 'the key' 并且您已将 'insert, ignore if it is already there' 缩减为标准 UPSERT。
在 psql 中,您可以执行 ON CONFLICT。搜索 'mysql upsert' 可以让您找到根据您的具体需求提供不同策略的博客文章,使用 INSERT IGNORE
(我建议不要这样做,这会忽略所有错误,而只忽略 'already in here' 仅错误),在重复密钥更新时(更好的主意,这个),或使用替换。
对于您在此处使用的任何数据库引擎,都可以找到类似的博文。
*) 未定义为 'as per some version of the SQL standard',而是定义为:'works in the majority of existing DB engines'.
如果你使用的SQLite版本是3.24.0+并且city
列有唯一约束,你可以使用upsert
如果发生 唯一约束违规 ,这使您可以选择执行 NOTHING
或 UPDATE
table。
在这种情况下:
String sql =
"INSERT INTO weather VALUES(?,?,?,?,?,?,?) " +
"ON CONFLICT DO NOTHING";
如果您尝试插入具有现有 city
的行,该语句将失败且不会出现错误。
但是如果新行包含其他列的最新数据并且您希望更新该行,您可以这样做:
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
定义唯一约束并且您不想或不能定义一个,那么您可以避免使用 NOT EXISTS
插入同一个城市两次,例如这个:
String sql =
"INSERT INTO weather SELECT ?,?,?,?,?,?,? " +
"WHERE NOT EXISTS (SELECT 1 FROM weather WHERE city = ?);
在这种情况下,您必须将 Java 代码作为附加的第 8 个参数再次传递给 city
的值。