INSERT ON DUPLICATE KEY UPDATE не может обновить одну и ту же строку дважды - PullRequest
0 голосов
/ 20 октября 2018

Я пытаюсь использовать sql в Mysql

INSERT INTO product_sales (product_code,product_desc,product_quantity,product_sales,product_group,insert_time) 
VALUES ('ZSHA','AAA','1','1.55','TESTING','$TEST time')
ON DUPLICATE KEY UPDATE 
    product_quantity = VALUES(product_quantity) + '123',
    product_sales = VALUES(product_sales) + '1.5',
    product_desc = 'hello',
    insert_time = 'hello';

Вот мой оператор создания таблицы:

CREATE TABLE `product_sales` (
    `product_code` varchar(20) NOT NULL DEFAULT '',
    `product_desc` longtext,
    `product_quantity` bigint(20) DEFAULT NULL,
    `product_sales` float DEFAULT NULL,
    `product_group` varchar(20) NOT NULL DEFAULT '',
    `insert_time` varchar(40) DEFAULT NULL,
    PRIMARY KEY (`product_code`,`product_group`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

Вот описание таблицы

| Field | Type | Null | Key | Default | Extra | +------------------+-------------+------+-----+---------+-------+ | product_code | varchar(20) | NO | PRI | | | | product_desc | longtext | YES | | NULL | | | product_quantity | bigint(20) | YES | | NULL | | | product_sales | float | YES | | NULL | | | product_group | varchar(20) | NO | PRI | | | | insert_time | varchar(40) | YES | | NULL |

Вот проблема, после того, как я вставил строку, этот запрос обновляет данные только один раз в базе данных, что означает, что после самого первого обновления данные больше не будут обновляться?

В чем проблема этого sql?

Ответы [ 2 ]

0 голосов
/ 20 октября 2018

Это способ сделать оператор вставки, если вы хотите продолжать добавлять значения в столбцы product_quantity и product_sales , сначала удалить VALUES () метод и второй (может быть необязательный) для пропуска автоматического приведения типов на движках, используйте целые числа и числа с плавающей запятой в SUM .

INSERT INTO product_sales (product_code,product_desc,product_quantity,product_sales,product_group,insert_time) 
VALUES ('ZSHA','AAA','1','1.55','TESTING','$TEST time')
ON DUPLICATE KEY UPDATE 
    product_quantity = product_quantity + 123,
    product_sales = product_sales + 1.5,
    product_desc = 'hello',
    insert_time = 'hello';

Я дам вам описание значенияМетод VALUES () следующий, так как я думаю, что вы его неправильно поняли:

VALUES () Объяснено:

В операторе INSERT ... ON DUPLICATE KEY UPDATE вы можетеиспользуйте функцию VALUES (col_name) в предложении UPDATE, чтобы ссылаться на значения столбца из части INSERT оператора.Другими словами, VALUES (col_name) в предложении UPDATE относится к значению col_name, которое было бы вставлено, если бы не произошло конфликта дублирующихся ключей.Эта функция особенно полезна при вставке нескольких строк.

0 голосов
/ 20 октября 2018

Кажется, работает нормально.Кажется, нет никаких проблем с SQL;похоже, он выполняет указанные операции;поведение, которое мы наблюдаем, точно такое же, как описано в документации Справочное руководство по MySQL.

При третьем выполнении изменения не применяются;результирующая строка будет точно соответствовать строке, которая уже сохранена.Таким образом, MySQL сообщает 0 row(s) affected, и строка остается неизменной.

После первого выполнения:

product_code product_desc product_quantity product_sales product_group insert_time  
------------ ------------ ---------------- ------------- ------------- ----------
ZSHA         AAA                         1          1.55 TESTING       $TEST time   

После второго выполнения:

------------ ------------ ---------------- ------------- ------------- ----------
ZSHA         hello                     124          3.05 TESTING       hello

После третьего выполнения (ичетвертый, пятый, ...):

------------ ------------ ---------------- ------------- ------------- ----------
ZSHA         hello                     124          3.05 TESTING       hello

Эти результаты в точности соответствуют ожиданиям.Не совсем понятно, зачем ожидать чего-то другого.(Может быть, мы не понимаем, что делает специальная функция VALUES()?)


Вопрос заставляет нас гадать ... какое поведение наблюдается и какое поведение ожидается.Сказать, что это «не работает», почти бесполезно с точки зрения объяснения.

Если мы хотим добавить значение, указанное в предложении VALUES, к существующему значению в столбце ...

INSERT INTO ... ( ... , product_quantity , ... )
VALUES ( ... , '1' , ... )
ON DUPLICATE KEY 
UPDATE product_quantity = IFNULL(product_quantity,0) + VALUES(product_quantity) 

При возникновении исключения из дубликата ключа будет получено текущее значение столбца product_quantity из строки.Если это ноль, мы возвращаем 0, в противном случае мы возвращаем значение, сохраненное в строке.Затем добавьте к этому значение, указанное в операторе INSERT для product_quantity.

Если мы не хотим, чтобы значение NULL перезаписывало текущее значение в столбце, мы можем также обернуть его в IFNULL или COALESCE

... 
ON DUPLICATE KEY 
UPDATE product_quantity = IFNULL(product_quantity,0) + IFNULL(VALUES(product_quantity),0)

Мы догадаемся о спецификации;угадать, что должен делать SQL, какое поведение мы хотим достичь.Без этого мы просто бросаем «пробовать этот» SQL без какого-либо определения того, удовлетворяет ли предложенный SQL спецификации.

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