2016-01-12 59 views
3

我們正在使用的德比,有很多的代碼是這樣的:我可以使用MERGE INTO模擬Apache Derby中的「upsert」嗎?

try (ResultSet rs = executeQuery(...)) { 
    if (rs.next()) { 
     updateRowSet(rs, ...); 
     rs.updateRow(); 
    } else { 
     executeUpdate(...); 
    } 
} 

在過去,我們正在尋找一種方式來做到這一點邏輯的服務器端,並發現一些數據庫的支持「upsert」(更新或插入)操作。德比有一個MERGE INTO的功能請求,據說這是SQL:2003標準的做法,所以我們坐下來看着票,花了很多時間。

德比10.11終於加了MERGE INTO。沒有人有時間通過​​並更新代碼來使用它,但是在閱讀他們的文檔時,他們的所有示例都顯示了從一個表到另一個表的合併。但請繼續,我們的數據還沒有在表格中!

我知道我可以它放在一個表中,但是它再次是多個查詢,這完全破壞了它的使用點。

我敢肯定有可能做到這一點沒有把它放到一個表中,但由於文檔沒有顯示一個例子,我不知道如何繼續。

這是我一直在努力:

try (PreparedStatement ps = connection.prepareStatement(
     "MERGE INTO things AS target " + 
     // Awkward point 1: 
     // It wants a "source" table, but I don't have one. 
     // So I thought I would try to use the same table with 
     // another name. 
     " USING things AS source ON target.id = ?" + 
     " WHEN MATCHED THEN" + 
     " UPDATE SET data = ?" + 
     " WHEN NOT MATCHED THEN" + 
     " INSERT (id, data) VALUES (??, ?)")) 
{ 
    ps.setLong(1, id); 
    ps.setBinaryStream(2, data); 
    ps.setLong(3, id); 
    // Awkward point 2: 
    // Passing an InputStream into a query as two 
    // parameters. 
    ps.setBinaryStream(4, data); 
    ps.execute(); 
} 

這似乎並沒有做任何的插件,也沒有給出一個錯誤,所以我絕對沒有什麼去。

+0

可能有用的相關問題:http://stackoverflow.com/questions/11216067/what-is-using-in-sql-server-2008-merge-syntax和http://stackoverflow.com/questions/2479488/ syntax-for-single-row-merge-upsert-in-sql-server –

+1

我不認爲德比可以這樣做。它不允許常量值作爲合併語句的「源」。 –

回答

0

以下爲我工作用Apache Derby 10.12.1.1:

merge into FOO 
using RANDOM_TABLE 
on FOO.guid = 'qwerty' 
when matched then 
    update set guid = 'qwerty' 
when not matched then 
    insert (guid) values('qwerty')  

這裏FOO是我的目標表做UPSERT進入和RANDOM_TABLE是我的數據庫中任何其他表。值「qwerty」是我的數據和唯一的關鍵。在這個例子中,FOO只有一個列,但它應該能夠分別向插入和更新添加更多的列。

我覺得這個語法相當不雅,但至少它似乎避免執行兩個單獨的語句來完成這項工作。

+0

奇怪,我剛剛得到錯誤代碼30000,SQL狀態42X01:語法錯誤:在第7行第12列遇到「INTO」。 – Hooli

相關問題