2016-05-09 32 views
0

递减值下似乎赔率对我说:对重复密钥更新 - 在MySQL

INSERT INTO sometable (UNIQUEVALUE,NUMERICVALUE) VALUES ('valuethatexists','100') ON DUPLICATE KEY UPDATE NUMERICVALUE = NUMERICVALUE+VALUES(NUMERICVALUE); 

假设你NUMERICVALUE为0时

以上将其更改为100 - 这确实工作。

但是,如果您输入-100,则无法正常工作。

INSERT INTO sometable (UNIQUEVALUE,NUMERICVALUE) VALUES ('valuethatexists','-100') ON DUPLICATE KEY UPDATE NUMERICVALUE = NUMERICVALUE+VALUES(NUMERICVALUE); 

上面的语句应该返回到0.它不是,在我的情况。它仍然在100.

我错过了什么吗?

编辑:这在别的地方出错了。我正在用PHP做这个。显示此错误的实际代码如下所示:

编辑2:这与PHP无关。问题是我的生产环境中的NUMERIC值为UNSIGNED,这意味着VALUES(NUMERICVALUE)在使用前从-100变为0。

回答

1

在我的MySQL服务器(5.7.12),它的工作如预期:

mysql> CREATE TABLE sometable (
     UNIQUEVALUE VARCHAR(16) NOT NULL PRIMARY KEY, 
     NUMERICVALUE INT NOT NULL); 
Query OK, 0 rows affected (0.01 sec) 

mysql> INSERT INTO sometable (UNIQUEVALUE,NUMERICVALUE) 
     VALUES ('valuethatexists','100') 
     ON DUPLICATE KEY UPDATE NUMERICVALUE = NUMERICVALUE+VALUES(NUMERICVALUE); 
Query OK, 1 row affected (0.01 sec) 

mysql> SELECT * FROM sometable; 
+-----------------+--------------+ 
| UNIQUEVALUE  | NUMERICVALUE | 
+-----------------+--------------+ 
| valuethatexists |   100 | 
+-----------------+--------------+ 
1 row in set (0.00 sec) 

mysql> INSERT INTO sometable (UNIQUEVALUE,NUMERICVALUE) 
     VALUES ('valuethatexists','-100') 
     ON DUPLICATE KEY UPDATE NUMERICVALUE = NUMERICVALUE+VALUES(NUMERICVALUE); 
Query OK, 2 rows affected (0.00 sec) 

mysql> SELECT * FROM sometable; 
+-----------------+--------------+ 
| UNIQUEVALUE  | NUMERICVALUE | 
+-----------------+--------------+ 
| valuethatexists |   0 | 
+-----------------+--------------+ 
1 row in set (0.00 sec) 

哪个版本的MySQL您使用的?你能否执行上面的确切陈述,看看你是否有不同的结果?

+0

我只是尝试SQLFiddel和我自己的5.7数据库。你是对的 - 它按预期做到了。我通过PHP来做这件事,显然这在其他地方是错误的。我会尝试进一步调查。 – nickdnk

+0

好,只要一次尝试隔离问题一步:) – Benjamin

+0

查看PHP示例更新的答案。 – nickdnk

0

虽然Benjamin的回答是正确的,但问题的根源竟然是NUMERICVALUE列是UNSIGNED,所以无论何时输入-100,在它被评估为VALUES(NUMERICVALUE)之前,它都变为0。如果这被认为是一个错误,我不知道。

显然,最终评估的结果不应该是负面的,但我不知道它是多么聪明,它默默地把它变成0.我有逻辑,确保有问题的价值永远不会低于0通过从不传递大于已经在行中的负值。