【问题标题】:INSERT INTO ... ON DUPLICATE UPDATE all valuesINSERT INTO ... ON DUPLICATE UPDATE all values
【发布时间】:2015-11-17 17:36:26
【问题描述】:

我可以像这样安全地更新所有值吗:

INSERT INTO tbl_name SET `a`=:a, `b`=:b, ... `z`=:z
ON DUPLICATE KEY UPDATE
`a`=VALUES(`a`), `b`=VALUES(`b`), ... `z`=VALUES(`z`);

我试过了,效果很好。但它只在一个 innodb 表上进行了测试。

我发现了这些相关问题123,但没有提到更新所有列(唯一和/或 pk)是 100% 安全的。

更新具有相同值的 PK 不会产生任何错误。
更新具有相同值的唯一 col 不会产生任何错误。

那么,使用它是否 100% 安全?如果不是,什么是极端情况,什么时候会破裂?

--------- 编辑 -------------
添加...最多z col

【问题讨论】:

  • 为什么需要使用当前值更新所有字段?
  • 我永远不会那样做!有些字段可能有新值,有些则没有。除了PK,任何领域都可以有新的价值。所有字段都可以有新值,或者只有一个字段可以有新值。基本上,它的工作原理类似于 pdo-db->save() 函数。
  • 只更新具有新值的字段有什么问题?
  • 因为我不知道什么时候以及哪些字段会有新的值。目前大约有 20 个字段,所有用户都可以更改。未来还会有更多的领域。我的 save() 方法有效。我只想知道它是否 100% 安全。
  • 您当前的代码所做的是更新表,然后如果唯一的键约束触发器使用其当前值更新所有字段。这是没有意义的,你可以只更新一个而不是全部,这仍然是一个 hack,但不幸的是,这是安全地做你想做的事情的唯一方法(afaik)。所以是的,这是安全的,你也不需要VALUES

标签: php mysql insert on-duplicate-key


【解决方案1】:

INSERT INTO … ON DUPLICATE KEY UPDATE 这样工作:

  • 它像往常一样尝试插入一行
  • 如果任何列中发生任何违反约束的情况,它将执行UPDATE 语句,而不是在与INSERT 语句冲突的现有行上执行

这仅仅意味着如果 UPDATE 语句单独成功,它的 ON DUPLICATE KEY UPDATE 等效语句也将起作用。这意味着您显然也不能违反UPDATE 语句中的任何约束,否则整个事情都会失败(例如,尝试在另一行中已经存在的UNIQUE 列上设置一个值)。

如果您再次在同一列上设置相同的值,则本质上是无操作。列中的值不会改变,因此也不会导致任何错误(假设您没有任何可能行为不端的真正时髦的BEFORE UPDATE 触发器)。列数在这里无关紧要,您可以在一个语句中更改尽可能多或尽可能少。

【讨论】:

  • 我们快要走出暮光之城了 :) 现在,If you set the same value on the same column again, that's essentially a no-op. 你确定这是空话还是 mysql 引擎盖下发生了其他事情?首先意味着始终更新所有列是 100% 安全的,第二个含义可能会有所不同。是的,列数无关紧要:)
  • 我不知道“无操作”有多低级,但尝试发出 UPDATE 语句用完全相同的值替换某些列:受影响的行 应该是 0。
猜你喜欢
  • 1970-01-01
  • 2011-01-29
  • 1970-01-01
  • 2017-01-11
  • 2016-10-29
  • 1970-01-01
  • 2017-02-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多