2012-01-12 36 views
0

通常当我需要插入/更新多行,我会产生(在PHP)像下面这样的语句:高效插入/更新变化的多行的列与MySQL(和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) 

(该表产品只在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)列的多个查询。首先,你必须单独做你的插入语句,使用mysql_insert_id()来添加ID,然后对每列执行一次更新查询,只包括需要特定列更新的元素。通常情况下,您最终会得到与列一样多的查询(除非您足够幸运,列中的某些重叠部分不会更新)。

  3. 对于不需要更新的值,请在SELECT查询中首先获取现有值,然后简单地生成INSERT ... ON DUPLICATE KEY UPDATE查询,如同在该帖子的顶部所写的那样。

据我可以从mysql 'on duplicate key' documentation告诉,没有办法忽略在一行一行地的基础值。 (显然使用NULL只是将该行的值设置为NULL。)有什么我失踪?

对于这些方法中哪一个最为有效,特别是在行数大于50且列数为5-10的情况下,有何想法?此外,对于每行仅更新1-2列的情况,尽管要更新的列在所有列中按行更改。

谢谢。

回答

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,请选择另一个标志值。

+0

完美!谢谢! – 2012-01-12 01:40:10