[英]How to avoid saving duplicates in @ManyToMany, but insert into mapping table?
[英]Avoid duplicates in INSERT INTO in the same table
我在 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(?,?,?,?,?,?,?);";
我想修改它,這樣我就不會插入城市重復項。 有人可以幫我嗎? 謝謝!
如果您使用的 SQLite 版本是3.24.0+並且列city
有一個唯一約束,您可以使用upsert
,如果發生唯一約束沖突,您可以選擇不執行NOTHING
或UPDATE
表。
在這種情況下:
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
的值。
在“有效的標准 SQL”* 中無法做到這一點。
但是,每個單獨的數據庫引擎通常都有一些方法來實現這個目標。
這個概念稱為合並或更新插入 - 這些是您可以在網絡上搜索的術語。 例如,只需搜索“如何 postgres upsert”。 之所以稱為 upsert,是因為更通用的應用是:如果我要插入的值的某個子集在數據庫中尚不存在,則使用此數據插入一個新行。 否則,為該子集找到具有相同值的行,然后用它更新所有其他值。 例如:“找到 ID 為 12345 的學生,然后將名稱更改為 'Joe Bloggs'。如果沒有包含該行的行,則創建它”。
使所有值成為“關鍵”,並且您已將“插入,如果它已經存在則忽略”減少到標准 UPSERT。
在 psql 中,您可以執行 ON CONFLICT。 搜索 'mysql upsert' 可以讓您閱讀博客文章,根據您的具體需求為您提供不同的策略,從使用INSERT IGNORE
(我反對這個,這會忽略任何和所有錯誤,而只忽略“已經在這里”錯誤) ), ON DUPLICATE KEY UPDATE (更好的主意, 這個), 或使用 REPLACE.
您在此處使用的任何數據庫引擎都可以找到類似的博客文章。
*) 不是定義為“根據 SQL 標准的某些版本”,而是定義為:“適用於大多數現有數據庫引擎”。
您現在可以使用on conflict
。 這要求您對city
具有唯一索引/約束,但它已被定義為主鍵。 查看。
insert into weather ( . . . )
values ( . . . )
on conflict (city) ignore;
SQLite 也允許這種速記:
insert or ignore into weather ( . . . )
values ( . . . );
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.