是否可以强制 Sequel 始终返回带有重复密钥更新的 autoincrement id?
Can Sequel be forced to always return autoincrement id with ON DUPLICATE KEY UPDATE?
我正在使用 Sequel (4.x) 和 MySQL 5.5,在一个主要执行 INSERT
且偶尔执行的重写应用程序上更新现有行。 Sequel 在 .insert()
操作后返回一个 AUTO_INCREMENT
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
)
这会在新插入行或列的值更改时将自动increment id(LAST_INSERT_ID()
)返回到变量id
,但如果返回0
没有列的值被修改。
阅读 MySQL 文档,我明白为什么了。当执行 MySQL INSERT...ON DUPLICATE KEY UPDATE
时,MySQL 无法可靠地返回已存在但未被 UPDATE
更改的行的 AUTO_INCREMENT
id。文档建议使用 UPDATE
表达式,例如:
ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)
我真的很想在这个特定的应用程序中避免额外的 SELECT
。我如何强制 Sequel 使用相同的行为,并始终返回行 id
即使没有任何实际更改?
可以导致 Sequel 在 RDBMS 上执行一个函数
要执行 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
)
此方法可靠地 returns 将 LAST_INSERT_ID()
转换为 id
,而无需执行 SELECT
查询。
注意: INSERT...ON DUPLICATE KEY UPDATE
将导致table的AUTO_INCREMENT
值前进如果 table 包含除 AUTO_INCREMENT
主键之外的任何其他 UNIQUE
索引,则更新行时。这不是 Sequel 特有的,只是使用 ON DUPLICATE KEY UPDATE
.
时的一般警告
如果这不是 acceptable,您可能需要求助于单独的 SELECT
而不是在 DB.insert()
returns [=27= 时检索 ID ].
我正在使用 Sequel (4.x) 和 MySQL 5.5,在一个主要执行 INSERT
且偶尔执行的重写应用程序上更新现有行。 Sequel 在 .insert()
操作后返回一个 AUTO_INCREMENT
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
)
这会在新插入行或列的值更改时将自动increment id(LAST_INSERT_ID()
)返回到变量id
,但如果返回0
没有列的值被修改。
阅读 MySQL 文档,我明白为什么了。当执行 MySQL INSERT...ON DUPLICATE KEY UPDATE
时,MySQL 无法可靠地返回已存在但未被 UPDATE
更改的行的 AUTO_INCREMENT
id。文档建议使用 UPDATE
表达式,例如:
ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id`)
我真的很想在这个特定的应用程序中避免额外的 SELECT
。我如何强制 Sequel 使用相同的行为,并始终返回行 id
即使没有任何实际更改?
要执行 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
)
此方法可靠地 returns 将 LAST_INSERT_ID()
转换为 id
,而无需执行 SELECT
查询。
注意: INSERT...ON DUPLICATE KEY UPDATE
将导致table的AUTO_INCREMENT
值前进如果 table 包含除 AUTO_INCREMENT
主键之外的任何其他 UNIQUE
索引,则更新行时。这不是 Sequel 特有的,只是使用 ON DUPLICATE KEY UPDATE
.
如果这不是 acceptable,您可能需要求助于单独的 SELECT
而不是在 DB.insert()
returns [=27= 时检索 ID ].