2015-01-01 73 views
0

我正在使用Sequel(4.x)和MySQL 5.5編寫大量應用程序,主要執行INSERT s並偶爾更新現有行。繼續執行.insert()操作後,續集會返回一個AUTO_INCREMENT ID。可以強制繼續使用ON DUPLICATE KEY UPDATE返回自動增量ID嗎?

我目前使用.on_duplicate_key_update()在表達式,如:

# Insert new row into cache_table, updating any columns that change 
# on a key violation 
id = DB[:table_name].on_duplicate_key_update.insert(
  col1: @col1, 
  col2: @col2, 
  created: nil, 
  updated: nil 
) 

這將返回自動遞增ID(LAST_INSERT_ID())到變量id當行新插入或列的值的變化,但回報0如果沒有列的值被修改。

閱讀MySQL docs,我明白爲什麼。當執行MySQL INSERT...ON DUPLICATE KEY UPDATE時,MySQL無法可靠地返回已存在但未被UPDATE更改的行的AUTO_INCREMENT id。該文檔建議使用像UPDATE表達:

ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`) 

我真的想避免額外的SELECT在這個特定的應用。我如何強制續集使用相同的行爲,並且始終返回行id,即使沒有任何實際更改?

回答

1

有可能引起後遺症使用於對RDBMS執行的函數Sequel.function() method

要執行MySQL的原生LAST_INSERT_ID()並通過列id作爲參數,通過列名作爲符號作爲第二個參數:

Sequel.function(:last_insert_id, :id) 

Dataset#on_duplicate_key_update method接受更新的列和新值的散列,所以:last_insert_id功能可通過在那裏,連同其他列的明確上市更新:

id = DB[:table_name].on_duplicate_key_update(
    # Call the native LAST_INSERT_ID() 
    id: Sequel.function(:last_insert_id, :id), 
    col1: @col1, 
    col2: @col2, 
    updated: nil 
).insert(
    col1: @col1, 
    col2: @col2, 
    created: nil, 
    updated: nil 
) 

這種方法可靠地返回到LAST_INSERT_ID()id,而無需做SELECT查詢。

注意INSERT...ON DUPLICATE KEY UPDATE導致表的AUTO_INCREMENT值提前如果表中包含除AUTO_INCREMENT主鍵的任何附加UNIQUE指數當行被更新。這不是特定於續集,只是使用ON DUPLICATE KEY UPDATE時的一般警告。

如果這是不可接受的,您可能需要求助於做一個單獨的SELECT而不是DB.insert()返回0時檢索id。

相關問題