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...
Related
This problem seems easy at first sight, but I simply have not found a solution that is reasonable time wise.
Consider a table with the following characteristics:
ID INTEGER PRIMARY KEY AUTOINCREMENT
name INTEGER
values1 INTEGER
values2 INTEGER
dates DATE
Every day, N amount of new rows are generated, for dates into the future, and with the 'name' coming from a finite list. I would like to insert a new row when there is new data, but if there is already a row with 'name' and 'dates', simply update it.
Please note that a current proposed solution of an SPROC that checks the conditional is not feasible, as this is data being pushed from another language.
that is what insert on duplicate key update is for.
The Manual page for it is here.
The trick is that the table needs to have a unique key (can be a composite) so that the clash of doing an insert can be detected. As such, the update to occur on that row, otherwise an insert. It can be a primary key, of course.
In your case, you could have a composite key such as
unique key(theName,theDate)
If the row is already there, the clash is detected, and the update happens.
Here is a complete example
create table myThing
( id int auto_increment primary key,
name int not null,
values1 int not null,
values2 int not null,
dates date not null,
unique key(name,dates) -- <---- this line here is darn important
);
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (778,1,1,'2015-07-11') on duplicate key update values2=values2+1;
-- do the 1st one a few more times:
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
insert myThing(name,values1,values2,dates) values (777,1,1,'2015-07-11') on duplicate key update values2=values2+1;
show results
select * from myThing;
+----+------+---------+---------+------------+
| id | name | values1 | values2 | dates |
+----+------+---------+---------+------------+
| 1 | 777 | 1 | 4 | 2015-07-11 |
| 2 | 778 | 1 | 1 | 2015-07-11 |
+----+------+---------+---------+------------+
As expected, insert on duplicate key update works, just 2 rows.
This is easy:
Create a unique key on the columns to check
Use the INSERT .. ON DUPLICATE KEY UPDATE construct
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 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.