使用MySQL(和PHP)有效地插入/更新多行的不同列

时间:2012-01-12 01:21:55

标签: php mysql insert

通常当我需要插入/更新多行时,我将生成(在PHP中)如下语句:

INSERT INTO Products (ProductID, Name, Weight, Color) VALUES 
(1001, "Product A", 14.5, "Red"),
(1002, "Product B", 12.3, "Green"),
(null, "Product C", 15.3, "Yellow"),
...
(null, "Product Z", 10.4, "Blue")
ON DUPLICATE KEY UPDATE 
    Name = VALUES(Name), 
    Weight = VALUES(Weight), 
    Color = Values(Color)

(表Products只有ProductID上的一个键,但是列数比这里更新的列多。)

我使用这种查询,因为可以通过迭代要插入/更新的产品集来生成插入/更新任意数量的产品。

但问题是,某些值不应更新。

如果可能的话,我想生成一个只能按行更新某些列的查询:

INSERT INTO Products (ProductID, Name, Weight, Color) VALUES 
(1001, "Product A", DO_NOT_UPDATE, "Red"),
(1002, "Product B", 12.3, DO_NOT_UPDATE),
(null, "Product C", 15.3, "Yellow"),
...
(null, "Product Z", 10.4, "Blue")
ON DUPLICATE KEY UPDATE 
    Name = VALUES(Name), 
    Weight = VALUES(Weight), 
    Color = Values(Color)

我可以想到三个选择:

  1. 生成多个查询,一次插入/更新一行。

  2. 生成多个查询,一次更新一个(非id)列。首先,您必须单独执行insert语句,使用mysql_insert_id()添加ID,然后每列执行一次更新查询,仅包括需要更新特定列的元素。一般来说,你最终会得到与列数一样多的查询(除非你很幸运,列中有一些重叠不能更新)。

  3. 对于不需要更新的值,请先在SELECT查询中获取现有值,然后只生成此帖子顶部所写的INSERT ... ON DUPLICATE KEY UPDATE查询。

  4. 据我所知mysql 'on duplicate key' documentation,无法逐行忽略值。 (显然使用NULL只是将该行的值设置为NULL。)我有什么遗漏的吗?

    关于哪种方法最有效的任何想法,特别是在行数> 1的情况下。 50和列数是5-10?同样,对于每行只更新1-2列的情况,尽管要更新的列在所有列中按行变化。

    感谢。

1 个答案:

答案 0 :(得分:1)

如果您不需要NULL作为字段的有效值,那么您可以执行以下操作:

INSERT INTO Products (ProductID, Name, Weight, Color) VALUES 
(1001, "Product A", NULL, "Red"),
(1002, "Product B", 12.3, NULL),
(null, "Product C", 15.3, "Yellow")
ON DUPLICATE KEY UPDATE 
    Name = IF(VALUES(Name) IS NULL, Name, VALUES(Name)), 
    Weight = IF(VALUES(Weight) IS NULL, Weight, VALUES(Weight)), 
    Color = IF(VALUES(Color) IS NULL, Color, VALUES(Color));

因此,如果您传递NULL,然后将UPDATE设置字段值设置为自身(从而有效地忽略操作)。否则,该字段将更新为新值。

如果确实需要NULL,请选择另一个标记值。