【问题标题】:Inserting & removing rows in a MySQL database without multiple queries在没有多个查询的情况下在 MySQL 数据库中插入和删除行
【发布时间】:2012-03-22 10:44:40
【问题描述】:

在阅读问题之前检查此示例 - http://www.sqlfiddle.com/#!2/fcf3e/8

以下数据来自一个表单,用户只是从特价中删除了一个产品。

Array(
    'special_offer_id' => 1,
    'product_ids' => Array(
        0 => 1,
        0 => 2
    )
)

本来我想用这个查询...

REPLACE INTO `foo` VALUES (1, 1), (2, 1);

但这不会删除用户删除的产品 - 只会更新其他产品。

所以我不得不执行 2 个查询...

DELETE FROM `foo` WHERE `special_offer_id` = 1;
INSERT INTO `foo` VALUES (1, 1), (2, 1);

有没有更好的方法来做到这一点而不必执行 2 次查询?

示例:http://www.sqlfiddle.com/#!2/fcf3e/8

【问题讨论】:

  • 多查询有什么问题?也许最好的方法是使用存储过程。
  • 它们没什么问题,我只是想知道是否有首选的方法。
  • 为什么你认为 REPLACE 不会删除记录?使用 SELECT ROW_COUNT() 查询检查这一点。您的 PK 是复合键(product_id、special_offer_id)。
  • 因为REPLACE INTO只会UPDATE数组中的2条记录而忽略被删除的那条。
  • REPLACE 语句首先检查唯一字段(product_id 和 special_offer_id),然后删除并插入新记录,或者只是插入新记录。在您的情况下,special_offer_id 字段不是唯一的。

标签: mysql query-optimization sql-insert sql-delete


【解决方案1】:

我认为在 MySQL 中组合 DML 语句是不可能的。我知道 Oracle 和 MSSQL 对此有合并功能,但我认为 MySQL 没有此功能,但我不太确定。

看看你的小提琴和代码的实际作用,我想出了一种不同的方法。如果您遍历存在的数据数组并将输出放入 1 个变量并使用 delete 删除不匹配的行。

这是一个基于您的 sqlfiddle 的示例(请注意,该数组无效,因为它在 fiddle 中未正确命名)

// Declare var and fill with array result
$exists = '';

for ($c = 0; $c < count($array); c++)
{
    if ($c == (count($array) -1))
    {
      $exists .= $array[$c]['product_ids'];
    }
    else
    {
      $exists .= $array[$c]['product_ids'].',';
    }
}

那么你可以用一个来完成,而不是做两个查询

DELETE FROM `foo` WHERE `special_offer_id` NOT IN ('.$exists.');

【讨论】:

    猜你喜欢
    • 2020-05-10
    • 1970-01-01
    • 2020-05-11
    • 2012-11-27
    • 1970-01-01
    • 1970-01-01
    • 2017-02-07
    • 1970-01-01
    • 2015-03-13
    相关资源
    最近更新 更多