I'm trying to use sql in 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';
Here is my Create table statement:
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
Here is the description of the table
| 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 |
Here is the problem, after i inserted the row, this query only update the data once in the database which means after the very first time update, the data won't update anymore?
What is the problem of this sql?
Seems to be working fine. There doesn't seem to be any problem with the SQL; it seems to be performing the specified operations; the behavior we observe is exactly as described in the documentation MySQL Reference Manual.
On the third execution, there are no changes to be applied; the resulting row will match exactly the row that is already stored. So MySQL reports 0 row(s) affected, and the row remains unchanged.
After first execution:
product_code product_desc product_quantity product_sales product_group insert_time
------------ ------------ ---------------- ------------- ------------- ----------
ZSHA AAA 1 1.55 TESTING $TEST time
After second execution:
------------ ------------ ---------------- ------------- ------------- ----------
ZSHA hello 124 3.05 TESTING hello
After third execution (and fourth, fifth, ...):
------------ ------------ ---------------- ------------- ------------- ----------
ZSHA hello 124 3.05 TESTING hello
These results are exactly as we would expect. It's not at all clear why would expect something different. (Maybe we're not understanding what the special VALUES() function does?)
The question leaves us guessing... what behavior is being observed, and what behavior is expected. Saying that it "is not working" is next to useless, in terms of explanation.
If we want to add the value supplied in the VALUES clause to the existing value in the column...
INSERT INTO ... ( ... , product_quantity , ... )
VALUES ( ... , '1' , ... )
ON DUPLICATE KEY
UPDATE product_quantity = IFNULL(product_quantity,0) + VALUES(product_quantity)
When a duplicate key exception occurs, this will get the current value of the product_quantity column from the row. If it's null, we return 0 otherwise we return the value stored in the row. Then add to that the value supplied in the INSERT statement for product_quantity.
If we don't want a NULL value to overwrite the current value in the column, we can wrap that in an IFNULL or COALESCE as well
...
ON DUPLICATE KEY
UPDATE product_quantity = IFNULL(product_quantity,0) + IFNULL(VALUES(product_quantity),0)
We're guessing at the specification; guessing at what the SQL is supposed to do, what behavior we want to achieve. Without that, we're just flinging "try this" SQL without anyway of determining if the proposed SQL satisfies the specification.
This is the way you have to do your insert statement if you want to keep adding values to columns product_quantity and product_sales, first remove VALUES() method, and second (maybe optional) for skip auto cast of types on engines, use integers and float numbers on the 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';
I let you a description of the meaning of VALUES() method next, since i think you misunderstand it:
VALUES() Explained:
In an INSERT ... ON DUPLICATE KEY UPDATE statement, you can use the VALUES(col_name) function in the UPDATE clause to refer to column values from the INSERT portion of the statement. In other words, VALUES(col_name) in the UPDATE clause refers to the value of col_name that would be inserted, had no duplicate-key conflict occurred. This function is especially useful in multiple-row inserts.
Related
I have a table with various fields including a primary key, id, which is auto-incrementing:
+-------------------------------+------------------+------+-----+---------+
| Field | Type | Null | Key | Default | Extra
+-------------------------------+------------------+------+-----+---------+
| id | tinyint(11) | NO | PRI | NULL | auto_increment
The table is already populated with 114 items:
mysql> select count(*) as cnt from beer;
+-----+
| cnt |
+-----+
| 114 |
+-----+
And I am trying to insert a group of new items into the table. I am not explicitly inserting an id key. Here's a sample query:
mysql> INSERT INTO beer (name, type, alcohol_by_volume, description, image_url)
VALUES('Test Ale', 1, '4.6', '', 'https://untappd.s3.amazonaws.com/site/assets/images/temp/badge-beer-default.png');
I get the following error when attempting to manually insert that query (the insertion is actually done with a PHP script to the same results):
ERROR 1062 (23000): Duplicate entry '127' for key 1
What's going on? I thought the id would automatically increment upon insertion. I should note that the first 13 entries are blank/null for some reason, and the last key is currently 127. (it's not my table -- I'm just writing the script).
Tiny int is not the good choice for auto_increment primary key... Range is just (-128...127). Normally it's used as a flag; you need to use unsigned int
Try resetting the auto increment of primary key manually using this:
ALTER TABLE `beer` AUTO_INCREMENT = 128;
I have a table which only has two column:
+------------------+-------------+----------------------------+
| user_id | INT | AUTO_INCREMENT |
+------------------+-------------+----------------------------+
| user_timestamp | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP |
+------------------+-------------+----------------------------+
Now I am quite confused how will I build my INSERT since all the values has default. I have this but seems not working $query = "INSERT INTO tt_users (user_id) VALUES ()";. I just want MySQL to insert a new user_id which I will retrieve using lastInsertID. Pardon, this is my first time doing this.
INSERT INTO tt_users (user_id) VALUES (null)
you can not insert the user_id.. that one is generated automatically. that's why you have AUTO_INCREMENT .. you can only insert timestamp, and even that is optional since you do have a default value assigned...
I have this table in a mysql database:
mysql> show columns from wifi_network_config_auth_algorithm;
+------------------------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+-------------+------+-----+---------+-------+
| wifi_network_config_id | int(11) | NO | PRI | NULL | |
| auth_algorithm | varchar(50) | NO | PRI | NULL | |
+------------------------+-------------+------+-----+---------+-------+
The table was created using liquibase. Table creation itself does not define primary keys. Following table creation, the following liquibase command is used to set the combination of 2 columns as the primary key:
<addPrimaryKey tableName="wifi_network_config_auth_algorithm"
columnNames="wifi_network_config_id,auth_algorithm"
constraintName="pk_wifi_network_config_auth_algorithm"/>
Now, when you execute this to load data into this table:
LOCK TABLES `wifi_network_config_auth_algorithm` WRITE;
INSERT INTO `wifi_network_config_auth_algorithm` VALUES
(1, 'OPEN'),
(1, 'SHARED'),
(2, 'SHARED'),
(2, 'LEAP');
UNLOCK TABLES;
You get:
ERROR 1062 (23000): Duplicate entry '1' for key 2
Since the combination of both columns is the primary key, so the combination of the data in the two columns should be unique - which is true for the data shown above. Why is mysql complaining?
Also, it's complaining that the value '1' is being assigned to key 2, which does not make sense. I changed the INSERT to:
INSERT INTO `wifi_network_config_auth_algorithm` (`wifi_network_config_id`, `auth_algorithm`)
but it did not make any difference - same complaint from mysql.
Thanks,
Hari
This works for me. Is the table empty or missing these values before you execute the insert statement?
If I run this example twice I get an error message:
Duplicate entry '1-OPEN' for key 'PRIMARY'
Calling DELETE FROM wifi_network_config_auth_algorithm first avoids that.
Otherwise there must be something wrong with the way the primary key was created, since your error message differs.
I created a test table using the following:
CREATE TABLE `test` (
`wifi` int(11) NOT NULL,
`auth` varchar(50) NOT NULL,
PRIMARY KEY (`wifi`,`auth`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1
Figured out the issue with #kbenson's help. The answer is in the comments for the original question.
Consider the following table:
+-------------+------------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+------------------+------+-----+---------+----------------+
| vendor_id | int(10) unsigned | NO | PRI | NULL | auto_increment |
| vendor_name | varchar(100) | NO | UNI | NULL | |
| count | int(10) unsigned | NO | | 1 | |
+-------------+------------------+------+-----+---------+----------------+
I have the following MySQL query:
INSERT INTO `table`
(`vendor_name`)
VALUES
('foobar') ON DUPLICATE KEY UPDATE `count` = `count` + 1
The intent of this query is to insert a new vendor name to the table and in case the vendor name already exists, the column count should be incremented by 1. This works however the primary key of the current column will also be auto-incremented. How can I prevent MySQL from auto-incrementing the primary key in these cases? Is there a way to do this with one query?
Thank you.
This works however the primary key of the current column will also be auto-incremented. How can I prevent MySQL from auto-incrementing the primary key in these cases?
By using an UPDATE statement when the value already exists:
IF EXISTS(SELECT NULL
FROM TABLE
WHERE vendor_name = $vendor_name) THEN
UPDATE TABLE
SET count = count + 1
WHERE vendor_name = $vendor_name
ELSE
INSERT INTO TABLE
(vendor_name)
VALUES
($vendor_name
END IF
I tried the alternative to ON DUPLICATE KEY UPDATE, REPLACE INTO:
REPLACE INTO vendors SET vendor_name = 'foobar', COUNT = COUNT + 1
It updates the count, and the vendor_id so it's worse...
The database & data doesn't care if the numbers aren't sequential, only that the values are unique. If you can live with that, I'd use the ON DUPLICATE UPDATE syntax though I admit the behaviour is weird (understandable considering using an INSERT statement).
I think this might do it. But it's very much against the principles of Daoism - you're really going against the grain.
There is probably a better solution.
INSERT INTO `table`
(`vendor_name`)
VALUES
('foobar') ON DUPLICATE KEY UPDATE `count` = `count` + 1, `vendor_id`=`vendor_id`-1
Consider the following SQL:
CREATE TABLE USER1
(
pkUSER1_ID INT UNSIGNED NOT NULL AUTO_INCREMENT,
DATE_UPDATED TIMESTAMP NULL DEFAULT NULL,
NAME VARCHAR(25) NOT NULL,
CONSTRAINT PRIMARY KEY (pkUSER1_ID),
CONSTRAINT UNIQUE (NAME)
)
ENGINE = INNODB;
INSERT INTO USER1
SET NAME = 'asdf'
ON DUPLICATE KEY
UPDATE DATE_UPDATED = NOW();
INSERT INTO USER1
SET NAME = 'asdf'
ON DUPLICATE KEY
UPDATE DATE_UPDATED = NOW();
INSERT INTO USER1
SET NAME = 'asdf1'
ON DUPLICATE KEY
UPDATE DATE_UPDATED = NOW();
SELECT * FROM USER1;
And now notice the result set. The auto_increment was increased despite nothing being inserted.
+------------+---------------------+-------+
| pkUSER1_ID | DATE_UPDATED | NAME |
+------------+---------------------+-------+
| 1 | 2010-02-09 13:29:15 | asdf |
| 3 | NULL | asdf1 |
+------------+---------------------+-------+
I get different behavior on two separate servers... the output above is from MySQL v5.0.45 running on 2.6.9-023stab048.6-enterprise (I think it's Red Hat). The problem doesn't exist on MySQL v5.0.51a-24+lenny2-log running on 2.6.26-2-amd64 (which is obviously Debian).
Is there a configuration setting I can change to avoid this? I have around 300 users in my database, but due frequency that the insert/update statement is run, the latest user id is over 600,000.
This is a bug... http://bugs.mysql.com/bug.php?id=28781
Not sure why the client is running a 3 year old version of MySQL.