We have a table:
id int(11) auto_increment
name varchar(255)
auto_increment equals 1.
Insert row:
INSERT INTO `projects` ( `id` , `name`) VALUES ('350', 'project one');
Now auto_increment equals 351.
Update row:
UPDATE `projects` SET `id` = '351' WHERE `id` = 350 LIMIT 1 ;
auto_increment still equals 351. And we get error if try to insert a row:
#1062 - Duplicate entry '351' for key 1
How we can see INSERT changes auto_increment and UPDATE not changes auto_increment.
My goal is to update row and set id greater then auto_increment.
How to do it?
First of all why are you trying to set the auto increment value? Just let it do its job (clue - it is automatic).
So the best solution is when you insert a row let the auto increment chose the appropriate value for you and let that value be an invariant for that rows life time.
Otherwise just remove the auto_increment bit from the table definition and implement an appropriate system yourself.
Related
Is it possible to update only a single field with ON DUPLICATE KEY UPDATE in a table with multiple fields?
If I have a table with three fields; key, cats, dogs where key is the primary key is it possible to update a record on duplicate key, changing only one field, (for my example cats) without changing the value in the other non-key fields (dogs). This is without knowing what the value of dogs from outside of the database at the time of insertion (i.e. I have a variable holding cats value, but not one holding dogs value)
INSERT INTO `myTable` (`key`,`cats`) VALUES('someKey1','Manx') ON DUPLICATE KEY UPDATE `cats` = 'Manx';
At the moment when I run something like this and the key already exists in the table dogs is set to NULL even when it had a value previously.
Gordon is right, it does not work the way I described. If you see this, it is not caused by the ON DUPLICATE UPDATE statement, but something else. Here is the proof:
CREATE TABLE IF NOT EXISTS `myTable` (
`key` varchar(20) NOT NULL default '',
`cats` varchar(20) default NULL,
`dogs` varchar(20) default NULL,
PRIMARY KEY (`key`)
)
The run
INSERT INTO `myTable` (`key`, `cats`, `dogs`) VALUES
('someKey1', NULL, 'jack-russell');
Then run
INSERT INTO `myTable` (`key`,`cats`) VALUES
('someKey1','Manx') ON DUPLICATE KEY UPDATE `cats` = 'manx';
Then check the table
I think you should try to UPSERT.
Please examine this:
INSERT INTO `item` (`item_name`, items_in_stock) VALUES( 'A', 27)
ON DUPLICATE KEY UPDATE `new_items_count` = `new_items_count` + 27
MySQL UPSERT
I am having one table in which ID column is 'Auto Increment' set.
CREATE TABLE tablename(
ID int(11) unsigned int not null auto_increment,
Name varchar(20)
)ENGINE=InnoDB DEFAULT CHARSET=utf8;
Now I have one row in table whose ID filed is 100. But I want to move this row to the next auto incremental value. Let's say if the last row entered in the table is 1005 so row of ID=100 will move to 1006.
Simple way to solve this problem is
Select -> Insert -> Delete
But I want to know if I can do something like below:
UPDATE table SET ID=last_insert_id()+1 where ID=100
I've been getting this error from an insert on duplicate update query in MYSQL randomly every now and then.
Any idea what's going on? I can't seem to reproduce the error consistently it occurs sometimes and then sometimes not.
Here is the query in question:
INSERT INTO friendships (u_id_1,u_id_2,status) VALUES (?,?,'active') ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id);
And the schema describing the table is:
DROP TABLE IF EXISTS `friendships`;
CREATE TABLE `friendships` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`u_id_1` int(11) NOT NULL,
`u_id_2` int(11) NOT NULL,
`status` enum('active','pending','rejected','blocked') DEFAULT 'pending' NOT NULL,
`initiatiator` enum('1','2','system') DEFAULT 'system' NOT NULL,
`terminator` enum('1','2','system') DEFAULT NULL,
`confirm_timestamp` timestamp DEFAULT NULL,
`created` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE KEY (`u_id_1`,`u_id_2`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Your ON DUPLICATE KEY UPDATE statement isn't helping you at all here.
You are taking the LAST_INSERT_ID, which is the auto inc of the last successfully inserted row, and trying to update the duplicated row with that id. This will always cause a duplicate primary (you're trying to change the id of some row to match the id of the last thing you added)
If your goal is to either
Insert a new row, or
Update an existing row with 'active'
Then
INSERT INTO friendships (u_id_1,u_id_2,status)
VALUES ( ? , ? ,'active')
ON DUPLICATE KEY UPDATE
status = 'active'; -- I changed this
A separate consideration is to check the source for duplicates. I had a simple audit table
INSERT INTO table
field1, field2, ... , field3
ON DUPLICATE KEY UPDATE row_id=row_id;
where field1 is an INDEX but not UNIQUE with row_ID as INTEGER UNSIGNED AUTO_INCREMENT PRIMARY KEY.
Ran for years, but an unexpected duplicate row triggered this error.
Fixed by de-duping the source.
Possibly a trivial point to many readers here, but it cost me some head-scratching (followed by a facepalm).
In MySQL, you can insert a row and update the 'last insert ID' at the same time. I'm using this trick to be able to insert items conditionally (uniqueness) and still get the unique ID in all cases.
The code below works. The problem is that the ON DUPLICATE KEY statement also updates the Auto_increment value. Is it possible to avoid that?
CREATE TABLE T(
id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
X VARCHAR(64) NOT NULL UNIQUE
) ENGINE = InnoDB DEFAULT CHARSET=utf8;
INSERT INTO T(X) VALUES ('x') ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id);
SELECT LAST_INSERT_ID();
INSERT INTO T(X) VALUES ('x') ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id);
SELECT LAST_INSERT_ID();
Now we have one entry with id=1. However, the next entry will have id=3 since the Auto_increment value was updated when the second INSERT failed. This can be checked as follows:
SELECT Auto_increment FROM information_schema.tables WHERE table_name = 't'
AND table_schema = DATABASE();
Q: Is it possible to use this trick (or equivalent) and keep the Auto_increment value? Obviously, in this case, it doesn't need to get updated.
Is there anyway I can restrict the amount of rows allowed in a table to say 40, and then when 41st is added, the table deletes the first one?
Yes, you could do this with a trigger. What RDMS are you using?
CREATE TABLE animals (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
name CHAR(30) NOT NULL,
PRIMARY KEY (id)
);
-- if this is 41st record, ...
-- the statement below will delete the id with 1, and so forth
insert into animals(name) values('wolverine');
delete from animals where id <= LAST_INSERT_ID() - 40;