Эффективно вставлять / обновлять различные столбцы из нескольких строк с MySQL (и PHP) - PullRequest
0 голосов
/ 12 января 2012

Обычно, когда мне нужно вставить / обновить несколько строк, я сгенерирую (в 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) столбец за один раз.Сначала вам нужно будет выполнить оператор вставки отдельно, использовать mysql_insert_id () для добавления идентификаторов, а затем выполнить один запрос на обновление для каждого столбца, включая только элементы, для которых требуется конкретный столбец.Как правило, у вас будет столько запросов, сколько у вас есть столбцов (если только вам не повезло, что в столбцах не было совпадений, которые нельзя обновить).

  3. Для значений, не нуждающихся вобновить, сначала получить существующие значения в запросе SELECT, а затем просто сгенерировать запрос INSERT ... ON DUPLICATE KEY UPDATE, как написано в начале этого поста.

Насколько я могу судить по mysql 'на дублирующем ключе' документация , нет способа игнорировать значение построчно.(Очевидно, что использование NULL просто установит значение этой строки на NULL.) Есть ли что-то, чего я пропускаю?

Есть мысли о том, какой из этих методов будет наиболее эффективным, особенно вслучай, когда количество строк> 50, а количество столбцов 5-10?Также для случая, когда требуется обновить только 1-2 столбца на строку, хотя обновляемые столбцы различаются в зависимости от строки для всех столбцов.

Спасибо.

1 Ответ

1 голос
/ 12 января 2012

Если вам не нужно 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, выберите другое значение флага.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...