ON DUPLICATE KEY UPDATE... how to update an AUTO INCREMENT? - mysql

CREATE TABLE `feeds` (
`FEED_ID` bigint(20) unsigned NOT NULL AUTO_INCREMENT,
`P_ID` bigint(20) NOT NULL,
`P_NAME` varchar(100) NOT NULL,
PRIMARY KEY (`P_ID`),
UNIQUE KEY `FEED_ID` (`FEED_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8
::
INSERT INTO `table_a` (`P_ID`,`P_NAME`) VALUES ('30','John')
ON DUPLICATE KEY UPDATE `P_ID`= VALUES(`P_ID`),`P_NAME`= VALUES(`P_NAME`);
I would like to use INSERT.. ON DUPLICATE KEY UPDATE
where anytime I create that insert, I'd like the FEED_ID to auto increment.
As for now it stays the same because there was no new row insertion...
Should I delete then insert?

It would seem like you're looking for REPLACE instead of INSERT ... ON DUPLICATE KEY; it will remove the old row if one exists with a conflicting primary key or unique key, and insert a new one with a new FEED_ID;
REPLACE INTO feeds (p_id,p_name) VALUES (1,'Olle');
An SQLfiddle to test with.

Related

MySQL: 1:n relationship with auto increasing PK

I've two tables: users and files. A user can create files (1:n relationship).
When a user is deleted, all the user files refered to the user should be deleted, too. Deleting single files of a user should also be possible.
Try 1
CREATE TABLE `users` (
`user_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`password` VARCHAR(60) NOT NULL,
`salt` VARCHAR(33) NOT NULL,
`user_group_id` INT NOT NULL,
PRIMARY KEY (`user_id`),
CONSTRAINT `fk_u_user_group` FOREIGN KEY (`user_group_id`) REFERENCES `user_groups` (`user_group_id`) ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `user_file` (
`user_id` INT NOT NULL,
`user_file_id` INT NOT NULL,
`name` VARCHAR(50) NOT NULL,
`content` JSON DEFAULT NULL,
PRIMARY KEY ( `user_id`, `user_file_id`),
CONSTRAINT `fk_uf_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON UPDATE CASCADE ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
The table user_files contains files of all users so the primary key have to be a composition of user_id and user_file_id.
This solution works for me but there is one problem: The user_file_id is not increased automatically (because it's not the primary key). But I do not want to know the user_file_id when inserting new files to the table.
INSERT INTO user_files VALUES(1, ???, 'New file', default)
The default keyword instead of ??? is not working here.
Try 2
Another solution I though of would be to create a new table user_user_files that merges the tables users and user_files.
CREATE TABLE `user_file` (
`user_file_id` INT NOT NULL AUTO_INCREMENT,
`name` VARCHAR(50) NOT NULL,
`content` JSON DEFAULT NULL,
PRIMARY KEY (`user_file_id`),
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
CREATE TABLE `user_user_files`(
`user_id` INT NOT NULL,
`user_file_id` INT NOT NULL,
PRIMARY KEY(`user_id`, `user_file_id`),
CONSTRAINT `fk_uuf_user_id` FOREIGN KEY (`user_id`) REFERENCES `users` (`user_id`) ON UPDATE CASCADE ON DELETE CASCADE,
CONSTRAINT `fk_uuf_user_file_id` FOREIGN KEY (`user_file_id`) REFERENCES `user_files` (`user_file_id`) ON UPDATE CASCADE ON DELETE CASCADE
)ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci;
With that I could create a trigger when inserting a new row into user_files and that trigger would add a new row to user_user_files.
DELIMITER $$
CREATE TRIGGER after_user_insert
AFTER INSERT
ON user_files FOR EACH ROW
BEGIN
INSERT INTO `user_user_files` VALUES(NEW.user_file_id,default, default);
END$$
DELIMITER ;
But is this possible when I want the following behavior?
Delete all user files when the user is deleted
Option to delete single user files from a user
Summary
So with try 1 there is the problem that the primary key is not increased automatically.
With try 2 I do not know if my desired behavior works with deleting / adding rows.

MySQL trigger insert after insert into another table

I want to add a foreign key into tblprowareinventory whenever I insert into tblprowareproducts:
tblProwareproducts
CREATE TABLE `tblprowareproducts` (
`ItemID` int(11) NOT NULL,
`ItemCode` varchar(30) NOT NULL,
`itemDescription` varchar(60) NOT NULL,
`Strand` varchar(30) NOT NULL,
`UnitCost` double NOT NULL,
`SaleCost` double NOT NULL,
`CategoryID_fk` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `tblprowareproducts`
ADD PRIMARY KEY (`ItemID`),
ADD KEY `CategoryID_fk` (`CategoryID_fk`);
ALTER TABLE `tblprowareproducts`
MODIFY `ItemID` int(11) NOT NULL AUTO_INCREMENT;
ALTER TABLE `tblprowareproducts`
ADD CONSTRAINT `tblprowareproducts_ibfk_1` FOREIGN KEY (`CategoryID_fk`) REFERENCES `tblprowarecategory` (`PCategoryID`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
tblProwareinventory
CREATE TABLE `tblprowareinventory` (
`inventoryID` int(11) NOT NULL,
`ItemID_FK` int(11) NOT NULL,
`DateOfInventory` date NOT NULL,
`CurrentQuantity` int(11) NOT NULL,
`TotalQuantity` int(11) NOT NULL,
`DeliveredQuantity` int(11) NOT NULL,
`PhysicalCount` int(11) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
ALTER TABLE `tblprowareinventory`
ADD PRIMARY KEY (`inventoryID`),
ADD KEY `ItemID_FK` (`ItemID_FK`);
ALTER TABLE `tblprowareinventory`
ADD CONSTRAINT `tblprowareinventory_ibfk_2` FOREIGN KEY (`ItemID_FK`) REFERENCES `tblprowareproducts` (`ItemID`) ON DELETE CASCADE ON UPDATE CASCADE;
COMMIT;
INSERT INTO tblprowareinventory(ItemID_FK)
VALUES ((SELECT ItemID FROM tblprowareproducts))
but I get this error:
You can use the following CREATE TRIGGER statement:
DELIMITER //
CREATE DEFINER = `root`#`localhost` TRIGGER AddToInventory AFTER INSERT ON tblprowareproducts
FOR EACH ROW
BEGIN
INSERT INTO tblprowareinventory (ItemID_FK) VALUES (NEW.ItemID);
END;//
DELIMITER ;
Note: You have to remove your current trigger on phpMyAdmin or with the following statement: DROP TRIGGER AddToInventory; to successfully run this CREATE TRIGGER statement.
The TRIGGER successfully add a new row to the tblprowareinventory table with the NEW.ItemID, but you defined a PRIMARY KEY on the inventoryID of tblprowareinventory table. That's OK, but after trying INSERT a second row on tblprowareinventory table, you should get an error:
#1062 - Duplicate entry '0' for key 'PRIMARY'
The TRIGGER tries to INSERT a second row on tblprowareinventory table with 0 on the inventoryID column. This is not possible because 0 can only exists once on the inventoryID column.
You can solve this issue using a AUTO_INCREMENT on the inventoryID column too:
ALTER TABLE `tblprowareinventory` MODIFY `inventoryID` INT(11) NOT NULL AUTO_INCREMENT;
To INSERT a new row on tblprowareproducts table I used the following statement:
INSERT INTO `tblprowareproducts` (`ItemID`, `ItemCode`, `itemDescription`, `Strand`, `UnitCost`, `SaleCost`, `CategoryID_fk`)
VALUES (NULL, '111', '111', '111', '1', '1', '1')

Mysql clone id with trigger

I have two tables:
CREATE TABLE IF NOT EXISTS `users` (
`id` int(8) NOT NULL AUTO_INCREMENT,
`username` varchar(45) NOT NULL,
`password` varchar(200) NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
CREATE TABLE IF NOT EXISTS `users_info` (
`id` int(8) NOT NULL,
`name` varchar(35) NOT NULL,
`address` varchar(35) NOT NULL,
PRIMARY KEY (`id`),
) ENGINE=MyISAM DEFAULT CHARSET=latin1;
I want that when an user is inserted in table users, to automatically insert a new row in table users_info that would contain the same id in the id column, as the users table.
When I do my inserts, I do them like this: INSERT INTO users (username,password) VALUES ('user1','pass1');
I believe that I should look at MySQL triggers. I did take a look but I don't know how to retrieve the key id from the users table for every last row that is inserted, supposing that other rows could be inserted in parallel in other threads.
If you create AFTER INSERT trigger, you can use NEW object:
CREATE
TRIGGER `aftInsert_users` AFTER INSERT ON `users`
FOR EACH ROW BEGIN
INSERT INTO users_info (itemID) VALUES (NEW.id);
END;
A trigger on after insert should work if you define default values for the columns defined as not null:
CREATE TRIGGER insert_users_info
AFTER INSERT ON `users`
FOR EACH ROW INSERT INTO `users_info` (id) VALUES (NEW.id);
See the MySQL documentation on triggers for more information.

Insert in to child table that have foreign key to an auto_increment column

Schema is as shown below
CREATE TABLE `country` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`country_name` varchar(45) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
CREATE TABLE `state_table` (
`id` int(11),
`state_name` varchar(45) DEFAULT NULL,
`country_id` int(11) NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`country_id`),
CONSTRAINT `country_fk` FOREIGN KEY (`country_id`)
REFERENCES `country` (`id`) ON DELETE CASCADE on update cascade
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COMMENT='';
When I tried to insert data into both tables, data is inserting in to parent table but it is not inserting in to child table and error here is
Schema Creation Failed: Cannot add or update a child row: a foreign key constraint fails (`db_2_3b712`.`state_table`, CONSTRAINT `country_fk` FOREIGN KEY (`country_id`) REFERENCES `country` (`id`) ON DELETE CASCADE ON UPDATE CASCADE):
As per my idea having country_id as auto_increment is creating problem.
I tried inserting like this
INSERT INTO country (country_name) VALUES ('US of A');
INSERT INTO state_table (state_name,id) VALUES
('Minnesota', 2),
('Arizona', 2);
Help me.
The id that you are inserting must exist in country table and has to be a valid id of a country.
Propably there is no country with id=2.
You can get the inserted id using function mysql_insert_id()
So it'd look like this:
INSERT INTO country (country_name) VALUES ('US of A');
INSERT INTO state_table (state_name,id) VALUES
('Minnesota', mysql_insert_id()),
('Arizona', mysql_insert_id());
Or even better you could assign this id to a variable and insert that.
INSERT INTO country (country_name) VALUES ('US of A');
$id = mysql_insert_id();
INSERT INTO state_table (state_name,id) VALUES
('Minnesota', $id),
('Arizona', $id);
Why do you have AUTO_INCREMENT to a foreign key constrained column? Delete AUTO_INCREMENT from country_id column and try again.

mysql cannot create foreign key

here are my two tables
CREATE TABLE IF NOT EXISTS `carslibrary` (
`CarID` int(10) unsigned NOT NULL AUTO_INCREMENT,
`CarName` varchar(255) NOT NULL,
`colorslibrary_ID` int(11) unsigned NOT NULL,
PRIMARY KEY (`CarID`),
KEY `colorslibrary_ID` (`colorslibrary_ID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=8 ;
CREATE TABLE IF NOT EXISTS `colorslibrary` (
`ColorID` int(11) unsigned NOT NULL AUTO_INCREMENT,
`ColorName` varchar(255) NOT NULL,
PRIMARY KEY (`ColorID`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=7 ;
I get an error on the following query:
ALTER TABLE `carslibrary` ADD FOREIGN KEY ( `colorslibrary_ID` )
REFERENCES `cars2`.`colorslibrary` (`ColorID` );
MySQL says:
#1452 - Cannot add or update a child row: a foreign key constraint
fails (`cars2`.<result 2 when explaining filename
'#sql-cf8_41a'>, CONSTRAINT `#sql-cf8_41a_ibfk_1` FOREIGN KEY
(`colorslibrary_ID`) REFERENCES `colorslibrary` (`ColorID`))
Your tables aren't empty, therefore a constraint fails (reference not found) when you create it.
Use SET FOREIGN_KEY_CHECKS = 0; and re-run your alter table.
I would firstly identify orphaned rows in the carslibrary table:
select * from carslibrary where colorslibrary_ID not in (select ColorID from cars2.colorslibrary);
Then decide what you want to do with these orphaned rows. Want to DELETE them from the carslibrary table? UPDATE them to an existing parent ColorID in the colorslibrary? INSERT a new ColorID in the colorslibrary table to cater for the orphaned rows?
Once you've tidied up your data you should be able to run the ALTER TABLE with no errors.