2013-03-06 42 views
5

我正在查找標準SQL「UPSERT」語句。一個呼叫插入和更新,如果存在。SQL標準UPSERT調用

我正在尋找一個工作,高效和跨平臺的電話。

我見過MERGE,UPSERT,REPLACE,INSERT .. 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) 
); 

任何想法?

感謝名單;)

+0

'INSERT ..對重複UPDATE'是'mYSQL'的關鍵。你能顯示一些記錄還是表格結構? – 2013-03-06 16:04:53

+0

是的,但它僅在MYSQL中受支持。 HSQLDB和所有其他人不使用它... – BobTheBuilder 2013-03-06 16:05:53

+0

有一個ANSI合併(http://en.wikipedia.org/wiki/Merge_%28SQL%29),但它沒有在所有DBMS中實現。所以沒有希望有一個通用的命令。 – 2013-03-06 16:07:04

回答

4

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

  1. START TRANSACTION。
  2. SELECT ... FOR UPDATE。
  3. 如果SELECT查找行,則更新。
  4. 其他,插入。
  5. COMMIT。

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


備註:是的,另一種方法是嘗試INSERT,看看它是否成功。否則,請執行UPDATE。如果您嘗試使用INSERT並且它碰到了重複鍵,則會生成一個錯誤,這在某些客戶端界面中會變成異常。在MySQL中這樣做的缺點是,即使INSERT失敗,它也會生成一個新的自動增量ID。所以你最終會有差距。我知道自動遞增序列中的差距通常不值得擔心,但去年我幫助了一個客戶,由於這種影響,他們之間的差距在1000-1500之間,插入成功,結果是他們耗盡了一個範圍INT在主鍵中。

正如@baraky所說,人們可以首先嚐試更新,如果這影響零行,那麼請改用INSERT。我對這個策略的評論是,更新零行不是一個例外 - 你必須在UPDATE之後檢查「受影響的行數」,以確定它是否「成功」。

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

HSQLDB:

CALL DIAGNOSTICS(ROW_COUNT); 

的MySQL:

SELECT ROW_COUNT(); 
+0

或者執行INSERT,捕獲SQLException,並且如果它違反了完整性約束,請執行UPDATE – fredt 2013-03-06 18:31:58

+0

實際上,這是(幾乎)我要做的 - 我要更新,捕獲異常(因爲更新是常見情況我)並插入如果失敗。感謝名單! – BobTheBuilder 2013-03-07 07:02:51

3

用於在單個命令做一個更新插入的語法由RDBMS不同而不同。

在MySQL中是INSERT...ON DUPLICATE KEY UPDATE

在HSQLDB是MERGE

如果你想要一個跨平臺的解決方案,那麼你就需要使用多個命令。首先檢查現有的行,然後根據情況有條件地插入或更新。

+0

我不想使用多個命令任何其他的想法如何測試和開發將運行相同的代碼 – BobTheBuilder 2013-03-06 16:15:25

+0

我仍然建議使用條件代碼來做它如果你不這樣做,那麼考慮標準化你的測試和dev環境使用相同的RD BMS。 – 2013-03-06 17:07:05

+0

@baraky:如果你想支持多個DBMS,你將永遠無法用在所有DBMS上運行的語句來解決所有問題。準備好具有DBMS特定聲明。其他一切都會失敗。 – 2013-03-06 17:31:22