insert-on-duplicate-key-update不能更新同一行两次

xqk2d5yq  于 2021-06-19  发布在  Mysql
关注(0)|答案(4)|浏览(352)

我正在尝试在mysql中使用sql

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语句:

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 | +

zz2j4svz

zz2j4svz1#

---+------+-----+---------+-------+ | 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有什么问题?

34gzjxbg

34gzjxbg2#

这是执行insert语句的方法,如果要继续向product\U quantity和product\U sales列添加值,请首先使用remove values()方法,然后(可能是可选的)对于跳过引擎上类型的自动转换,请在总和上使用整数和浮点数。

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()说明:
插入。。。在duplicate key update语句中,可以使用update子句中的values(col\u name)函数引用语句insert部分的列值。换句话说,update子句中的值(col\u name)指的是在没有出现重复键冲突的情况下将插入的col\u name的值。此函数在多行插入中特别有用。

nbysray5

nbysray53#

看起来很好。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 行中的列。如果为null,则返回0,否则返回行中存储的值。然后将insert语句中为product\ U quantity提供的值添加到该值中。
如果我们不希望null值覆盖列中的当前值,我们可以将其 Package 在ifnull或coalesce中

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

我们在猜测规格;猜测sql应该做什么,我们想要实现什么行为。如果没有这些,我们只是抛出“try this”sql,而不确定所建议的sql是否满足规范。

相关问题