Mysql clone id with trigger - mysql

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.

Related

Before Insert and After Update trigger on Same Table Not Working Properly

Dear Sir I have a master table tbl_appli_basic_info on this table I created two type of trigger one is after insert and other is before update trigger.I insert first record in master table mean when primary key is one it inserts record in master table Before insert trigger insert record in tbl_appli_basic_info_after_insert which I create separately. Secondly when I update primary key one record say in master table I insert name i.e ab now I update it to abc, after update trigger insert data in another table i.e tbl_appli_basic_info_after_update which I create separately too now issue is that when I update same data twice say name is abc now I changed it abcxzy it not allowed me to update the record My main purpose of using after insert trigger is that it maintain record once it inserts in master table after that I'm not used this table an after update trigger keep record of a single user how many time update the records with in different rows I am unable to manipulate the code please correct my code I will be great full to you.
DROP TABLE IF EXISTS `tbl_appli_basic_info`;
CREATE TABLE IF NOT EXISTS `tbl_appli_basic_info` (
`appli_basic_info_id` int(22) NOT NULL AUTO_INCREMENT,
`apli_reg_no` int(22) NOT NULL,
`full_name` varchar(256) NOT NULL,
PRIMARY KEY (`appli_basic_info_id`),
KEY `apli_reg_no` (`apli_reg_no`)
);
CREATE TABLE IF NOT EXISTS `tbl_appli_basic_info_after_insert` (
`appli_basic_info_id` int(22) NOT NULL AUTO_INCREMENT,
`apli_reg_no` int(22) NOT NULL,
`full_name` varchar(256) DEFAULT NULL,
PRIMARY KEY (`appli_basic_info_id`),
KEY `apli_reg_no` (`apli_reg_no`)
) ;
CREATE TABLE IF NOT EXISTS `tbl_appli_basic_info_after_update` (
`appli_basic_info_id` int(22) NOT NULL AUTO_INCREMENT,
`apli_reg_no` int(22) NOT NULL,
`full_name` varchar(256) NOT NULL,
PRIMARY KEY (`appli_basic_info_id`)
);
DROP TRIGGER IF EXISTS `trg_appli_basic_info_after_insert`;
DELIMITER $$
CREATE TRIGGER `trg_appli_basic_info_after_insert` AFTER INSERT ON `tbl_appli_basic_info` FOR EACH ROW BEGIN
-- Insert record into tbl_appli_basic_info_after_insert table
INSERT INTO tbl_appli_basic_info_after_insert
( appli_basic_info_id,
apli_reg_no,
full_name)
VALUES
( NEW.appli_basic_info_id,
NEW.apli_reg_no,
NEW.full_name
);
END
$$
DELIMITER ;
DROP TRIGGER IF EXISTS `trg_appli_basic_info_before_update`;
DELIMITER $$
CREATE TRIGGER `trg_appli_basic_info_before_update` BEFORE UPDATE ON `tbl_appli_basic_info` FOR EACH ROW BEGIN
-- Insert record into audit table
INSERT INTO tbl_appli_basic_info_before_update
( appli_basic_info_id,
apli_reg_no,
full_name
)
VALUES
( NEW.appli_basic_info_id,
NEW.apli_reg_no,
NEW.full_name
);
END
$$
DELIMITER ;
Your audit table definitions don't make a lot of sense and since you are defining appli_basic_info_id int(22) NOT NULL AUTO_INCREMENT Primary key and overwriting this in the triggers thus I would expect duplicate key errors. I would change the table definitions to
CREATE TABLE IF NOT EXISTS `tbl_appli_basic_info_after_insert` (
id int auto_increment primary key,
`appli_basic_info_id` int(22) ,
`apli_reg_no` int(22) NOT NULL,
`full_name` varchar(256) DEFAULT NULL,
PRIMARY KEY (id),
KEY `apli_reg_no` (`apli_reg_no`)
) ;
CREATE TABLE IF NOT EXISTS `tbl_appli_basic_info_after_update` (
id int auto_increment primary key,
`appli_basic_info_id` int(22) NOT NULL ,
`apli_reg_no` int(22) NOT NULL,
`full_name` varchar(256) NOT NULL,
PRIMARY KEY (id)
);

Auto increment Id value increased by 1 after insert trigger

I have 3 tables as below:
CREATE TABLE `user_dummy` (
`user_id` INT(11) NOT NULL AUTO_INCREMENT,
`user_name` VARCHAR(50) NOT NULL,
`user_email` VARCHAR(100) NOT NULL,
PRIMARY KEY (`user_id`)
)
ENGINE=InnoDB
;
CREATE TABLE `user_role` (
`user_role_id` INT(11) NOT NULL AUTO_INCREMENT,
`user_role_name` VARCHAR(255) NULL DEFAULT NULL,
PRIMARY KEY (`user_role_id`)
)
ENGINE=InnoDB
;
CREATE TABLE `user` (
`user_seq` INT(11) NOT NULL AUTO_INCREMENT,
`user_id` INT(11) NOT NULL,
`user_name` VARCHAR(50) NOT NULL,
`user_email` VARCHAR(100) NOT NULL,
`user_role_id` INT(11) NOT NULL,
PRIMARY KEY (`user_seq`),
INDEX `FKh2wc2dtfdo8maylne7mgubowq` (`user_role_id`),
CONSTRAINT `FKh2wc2dtfdo8maylne7mgubowq` FOREIGN KEY (`user_role_id`) REFERENCES `user_role` (`user_role_id`) ON UPDATE CASCADE ON DELETE CASCADE
)
ENGINE=InnoDB
;
I have created after insert trigger on user table.
i.e., when I insert 1 record into user_dummy table, it will insert records into table user table with all mappings of user_role.
trigger:
CREATE TRIGGER `user_dummy_after_insert` AFTER INSERT ON `user_dummy` FOR EACH ROW BEGIN
INSERT INTO user(user_id, user_name, user_email, user_role_id)
SELECT NEW.user_id, NEW.user_name, NEW.user_email, user_role_id
FROM user_role;
END
Above trigger is able to insert records into user table but the auto_increment value is incremented by 1 after each user_role record.
If you observe user_seq 3 is missing. And after inserting 4 records, auto_increment value set by trigger as 7.
How to fix this ?
Just an alternative: Better you could use the count function to count the total existing records and then increase it by one and assign according as. If you are interested to preserve the insertion sequence.

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: Stored procedure to insert data in many-to-many data model

I need to store data (entries and tags) with many-to-many relationship in MySQL. Should it matter, I am using a server with MySQL 5.7.
With the many-to-many relationship in mind, I created three tables: entries, tags, entries_tags.
Table for entries (entries):
CREATE TABLE `entries` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`date` datetime DEFAULT NULL,
`data1` double DEFAULT NULL,
`data2` varchar(150) DEFAULT NULL,
`data3` varchar(150) DEFAULT NULL,
`data4` varchar(150) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1;
Table for tags (tags):
CREATE TABLE `tags` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`tag_name` varchar(150) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
Table to store map entries-tags (entries_tags):
CREATE TABLE `entries_tags` (
`eID` int(11) NOT NULL,
`tID` int(11) NOT NULL,
PRIMARY KEY (`eID`,`tID`),
KEY `fk_tags_idx` (`tID`),
CONSTRAINT `fk_entries` FOREIGN KEY (`eID`) REFERENCES `entries` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `fk_tags` FOREIGN KEY (`tID`) REFERENCES `tags` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
I have also created a simple stored procedure to insert an entry in the entries table:
DELIMITER $$
CREATE DEFINER=user#localhost PROCEDURE insert_entry(
IN _date DATE,
IN _data1 DOUBLE,
IN _data2 VARCHAR(150),
IN _data3 VARCHAR(150),
IN _data4 VARCHAR(150)
)
BEGIN
INSERT INTO entries
(
date,
data1,
data2,
data3,
data4,
)
VALUES
(
_date,
_data1,
_data2,
_data3,
_data4,
);
END$$
DELIMITER ;
My goal is to have a stored procedure to insert the data in all three tables automatically. I want pass the following to the stored procedure:
date [datetime]
data1 [double]
data2 [varchar(150)]
data3 [varchar(150)]
data4 [varchar(150)]
tag_names [array of n strings]
After receiving the input, the stored procedure needs to:
insert a new row in the entries table using insert_entry
get the newly created entry id eID using SELECT LAST_INSERT_ID()
iterate over tag_names and get the corresponding tID from the tags table
insert the n rows (eID, tID) in entries_tags
If a particular tag_name does not exist in the tags table yet, it should be added in a new row.
I have little experience programming in MySQL and would appreciate your guidance/criticism regarding the approach I outlined above.
Do you think there is a better/easier way to do this? If yes, what is it? Please provide a simple code example.
Thanks!

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

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.