簡體   English   中英

SQL標准UPSERT調用

[英]SQL standard UPSERT call

我正在尋找一個標准的SQL“ UPSERT ”聲明。 如果存在,則插入和更新一次調用。

我正在尋找一個有效,高效的跨平台電話。

我見過MERGEUPSERTREPLACEINSERT .. ON DUPLICATE UPDATE但沒有聲明符合需求。

順便說一句,我使用MYSQL和HSQLDB進行unitests。 我知道HSQLDB是有限的,可能無法滿足我的需求,但即使沒有它,我也找不到標准的方法。 現在只有MYSQL和HSQLDB才足夠的聲明。

我一直在尋找一段時間,但無法得到答案。

我的桌子:

CREATE TABLE MY_TABLE (
  MY_KEY varchar(50) NOT NULL ,
  MY_VALUE varchar(50) DEFAULT NULL,
  TIME_STAMP bigint NOT NULL,
  PRIMARY KEY (MY_KEY)
);

任何的想法?

在單個命令中執行upsert的語法因RDBMS而異。

請參閱Wikipedia了解更多信息

如果您需要跨平台解決方案,那么您將需要使用多個命令。 首先檢查現有行,然后根據需要有條件地插入或更新。

MySQL和HSQLDB支持的唯一解決方案是查詢要替換的行,並有條件地查詢INSERT或UPDATE。 這意味着您必須編寫更多應用程序代碼來補償RDBMS實現之間的差異。

  1. 開始交易。
  2. SELECT ... FOR UPDATE。
  3. 如果SELECT找到行,則UPDATE。
  4. 另外,INSERT。
  5. 承諾。

MySQL不支持ANSI SQL MERGE語句。 它支持REPLACE和INSERT ... ON DUPLICATE KEY UPDATE。 有關詳細信息,請參閱我對“INSERT IGNORE”和“INSERT ... ON DUPLICATE KEY UPDATE”的回答。


評論:是的,另一種方法是嘗試INSERT並查看它是否成功。 否則,請進行更新。 如果您嘗試INSERT並且它遇到重復鍵,它將生成錯誤,這在某些客戶端接口中變為異常。 在MySQL中執行此操作的缺點是,即使INSERT失敗,它也會生成新的自動增量ID。 所以你最終會有差距。 我知道自動增量序列中的差距通常不值得擔心,但是我去年幫助了一位客戶,由於這種影響,成功插入之間的差距為1000-1500,結果是他們耗盡了范圍。 INT在他們的主鍵中。

正如@baraky所說,首先可以嘗試更新UPDATE,如果這會影響零行,則執行INSERT。 我對此策略的評論是,更新零行也不例外 - 您必須在UPDATE之后檢查“受影響的行數”以了解它是否“成功”。

但是查詢受影響的行數會使您回到最初的問題:您必須在MySQL和HSQLDB中使用不同的查詢。

HSQLDB:

CALL DIAGNOSTICS(ROW_COUNT);

MySQL的:

SELECT ROW_COUNT();

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM