Update row after insert from a another table - mysql

I use MySql and have two tables, master and inventory. Now I need a trigger after insert update inventory table field product_description from master table field product_description.
Example:
master table:
pmid - product_name - product_description - price
1 tv HD tv 10
inventory table:
invid - pmid - product_description - color
1 1 black
Trigger should insert product_description from partmaster where pmid = pmid.
CREATE TABLE IF NOT EXISTS `master` (
`pmid` int(11) NOT NULL AUTO_INCREMENT,
`product_name` varchar(255) NOT NULL,
`product_description` varchar(255) NOT NULL,
`price` varchar(10) NOT NULL,
PRIMARY KEY (`pmid`),
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;
CREATE TABLE IF NOT EXISTS `inventory` (
`invid` int(11) NOT NULL AUTO_INCREMENT,
`pmid` int(11) NOT NULL,
`product_description` varchar(255) NOT NULL,
`color` int(11) NOT NULL,
PRIMARY KEY (`invid`),
KEY `pmid` (`pmid`), //foreign key master table//
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=20 ;
Thanks

delimiter //
CREATE TRIGGER update_inventory AFTER INSERT ON master
FOR EACH ROW
BEGIN
UPDATE inventory I SET I.product_description = new.product_description
WHERE (I.pmid = new.pmid );
END; //
delimiter ;
I find your data inconsistent:
1. How can you have pmid in inventory without having it in master table?
2. Color field is numeric; contradicts your example.

Related

Create a table in a trigger and compare it

i have 4 tables and i want to create a trigger that it declares a table and store it all in that table so it can be compared latter.
CREATE TABLE IF NOT EXISTS `inventory` (
`id_product` INT(4) ZEROFILL NOT NULL AUTO_INCREMENT,
`model` varchar(45) NOT NULL,
`price_new` FLOAT DEFAULT '0',
`launch_date` DATE NOT NULL,
`stock` INT DEFAULT '0',
PRIMARY KEY (`id_product`));
CREATE TABLE IF NOT EXISTS `order` (
`id_order` INT(4) ZEROFILL NOT NULL AUTO_INCREMENT,
`id_customer` INT(6) ZEROFILL NOT NULL,
`subtotal` FLOAT DEFAULT '0',
`discount` float DEFAULT '0',
`tax_rate` float DEFAULT '0.23',
`total` float DEFAULT '0',
`date` DATETIME DEFAULT NOW(),
PRIMARY KEY (`id_order`),
CONSTRAINT `fk_order_1`
FOREIGN KEY (`id_customer`)
REFERENCES `iSAVE`.`customer` (`id_customer`)
ON DELETE RESTRICT
ON UPDATE CASCADE);
CREATE TABLE IF NOT EXISTS `order_item` (
`id_order_item` INT(4) ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY,
`id_product` INT(4) ZEROFILL NOT NULL,
`id_order` INT(4) ZEROFILL NOT NULL,
`quantity` INT DEFAULT NULL,
FOREIGN KEY (`id_product`) REFERENCES `iSAVE`.`inventory` (`id_product`),
FOREIGN KEY (`id_order`) REFERENCES `iSAVE`.`order` (`id_order`)
);
CREATE TABLE IF NOT EXISTS `transaction` (
`id_transaction` INT(4) ZEROFILL NOT NULL AUTO_INCREMENT PRIMARY KEY,
`id_order` INT(4) ZEROFILL NOT NULL,
`status` char(20) default 'Not completed',
FOREIGN KEY (`id_order`) REFERENCES `iSAVE`.`order` (`id_order`)
);
In here are the tables that im using. But now i have a trigger that after insert on orders it inserts on transactions. My objective now its to create a trigger that generates a table that takes order and order item and store id_product id_order and quantity so it can be used to after update on transaction the stock is changed on the respective items on tabel inventory.
This is the trigger that i have so far but i cant use it because i dont rly know how to declare a table in mysql:
delimiter $$
CREATE TRIGGER trigg1 after update on `transaction` for each row
BEGIN
declare #item TABLE(
id_order int,
id_product int,
quantity int);
update inventory i join #item it using (id_product)
set i.stock = i.stock - it.quantity
where it.id_order = new.id_order;
end $$
delimiter ;
You can't you have to use a temporaRY TABLE
delimiter $$
CREATE TRIGGER trigg1 after update on `transaction` for each row
BEGIN
CREATE TEMPORARY TABLE tbl1(
id_order int,
id_product int,
quantity int);
update inventory i join tbl1 it using (id_product)
set i.stock = i.stock - it.quantity
where it.id_order = new.id_order;
DROP TEMPORARY TABLE tbl1;
end $$
delimiter ;
But usually you make a temporaray atble with a select
CREATE TEMPORARY TABLE tbl1
SELECT id_order ,
id_product ,
quantity
FROM ORDERS

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 table with varchar primary key field

I have create users table with following structure
CREATE TABLE `users` (
`id` varchar(36) NOT NULL,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NULL,
`email` varchar(100) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
I just want to auto filled id value when we insert new row.
If you do wish to generate a uuid in conjuntion with a trigger then your table design has some problems for example
drop table if exists t;
CREATE TABLE t (
`id` varchar(36) not null,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NULL,
`email` varchar(100) NULL,
`password` varchar(100) NULL ,
PRIMARY KEY (`id`)
) ;
drop trigger if exists t;
delimiter $$
create trigger t before insert on t
for each row
begin
set new.id = (select uuid());
end $$
delimiter ;
truncate table t;
insert into t (first_name) values (1),(2);
ERROR 1364 (HY000): Field 'id' doesn't have a default value
And you cannot use a default value because a duplicate error will occur when attempting to insert (2);
And you cannot change the not null to null because the primary key has to have a value.
You can change the id to null and change the primary key to a unique key
drop table if exists t;
CREATE TABLE t (
`id` varchar(36) null,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NULL,
`email` varchar(100) NULL,
`password` varchar(100) NULL ,
unique key (`id`)
) ;
drop trigger if exists t;
create trigger t before insert on t
for each row
set new.id = (select uuid());
truncate table t;
insert into t (first_name) values (1),(2);
select * from t;
+--------------------------------------+------------+-----------+-------+----------+
| id | first_name | last_name | email | password |
+--------------------------------------+------------+-----------+-------+----------+
| 874bd297-adeb-11e8-b404-b8aeed249e19 | 1 | NULL | NULL | NULL |
| 874bda27-adeb-11e8-b404-b8aeed249e19 | 2 | NULL | NULL | NULL |
+--------------------------------------+------------+-----------+-------+----------+
2 rows in set (0.00 sec)
Try id int(11) NOT NULL AUTO_INCREMENT,
CREATE TABLE `users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`first_name` varchar(100) NOT NULL,
`last_name` varchar(100) NULL,
`email` varchar(100) NOT NULL,
`password` varchar(100) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
You're trying to make a VARCHAR column auto incrementing. You Can't Do Thatâ„¢.
VARCHAR columns containing the text of integers are notoriously hard to ORDER correctly.
In MySQL, an automatically filled (autoincrementing) ID column must have an integer datatype.
Try changing
`id` varchar(36) NOT NULL,
to
`id` UNSIGNED BIGINT NOT NULL AUTO_INCREMENT,
(I chose UNSIGNED BIGINT because it's the largest integer available, and your choice of 36 in your VARCHAR(36) makes it look like you are expecting an enormous number of rows in this table. But UNSIGNED INT will give you four gigarows, which is probably enough.)
If you choose to use a trigger or some other means to generate the autoincrementing values for your VARCHAR ID column, you will have to do a lot of hard work with transactions to avoid the possibility of duplicate values.
If your client software must see this column as a VARCHAR, you can do it in a view or select. SELECT CAST(id AS VARCHAR(36)) id does it.
Assuming you want an automatically generated GUID for the primary key, this only seems possible in MySql using a trigger.
CREATE TRIGGER before_insert_users
BEFORE INSERT ON users
FOR EACH ROW
BEGIN
IF new.id IS NULL THEN
SET new.id = uuid();
END IF;
END
More information can be found here:
https://www.electrictoolbox.com/mysql-guid-uuid-default-column/
According to Cookbook 3.x:
Rather than using an auto-increment key as the primary key, you may
also use char(36). CakePHP will then use a unique 36 character UUID
(Text::uuid) whenever you save a new record using the Table::save()
method.
Means CakePHP automatically saves a unique 36 character UUID (Text::uuid) whenever you save a new record using the Table::save() method.
Just change
id varchar(36) NOT NULL
to
id char(36) NOT NULL
Hope this will help!

Mysql : I want to create a trigger which will insert data into user access permission table based on employee table and categories table

I have three tables :- category ,employee and user_access_permission . I want to create a trigger that will fire when new category is added , insert values in user_access_permission for each employee id .default value for user_access is 0.
Category table :-
CREATE TABLE IF NOT EXISTS `categories` (
`category_id` int(11) NOT NULL AUTO_INCREMENT,
`category_name` varchar(100) NOT NULL,
`section_id` int(11) NOT NULL,
UNIQUE KEY `category_id` (`category_id`),
UNIQUE KEY `category_name` (`category_name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;
Employee table :-
CREATE TABLE IF NOT EXISTS `employee` (
`employee_id` int(11) NOT NULL AUTO_INCREMENT,
`emp_pass` varchar(50) NOT NULL,
`email` varchar(100) NOT NULL,
PRIMARY KEY (`employee_id`),
UNIQUE KEY `email_UNIQUE` (`email`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT=' ' AUTO_INCREMENT=1;
User Access Permission Table :-
CREATE TABLE IF NOT EXISTS `user_access_permission` (
`uap_id` int(10) NOT NULL AUTO_INCREMENT,
`section_id` int(10) NOT NULL,
`category_id` int(10) NOT NULL,
`employee_id` int(10) NOT NULL,
`access_level` int(10) NOT NULL DEFAULT '0',
PRIMARY KEY (`uap_id`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;
I am writing trigger like this :-
CREATE TRIGGER update_permssion_on_add_category
AFTER INSERT
ON categories FOR EACH ROW
insert into user_access_permission(section_id,category_id,employee_id,access_level) select(new.section_id,new.category_id,employee_id,0) from employee
But I don't get things right. Please Help
You have
select(new.section_id,new.category_id,employee_id,0) from employee
but section_id and category_id come from the category table.
I would suggest changing it to be 'from category' but the problem then is where do you get the employee_id number from? It's not anywhere in the original insert statement for the category table. Unless you decide to have it be some default value every time the trigger is fired.

MySQL ALBUM <- ALBUM_PHOTO -> PHOTO database model, foreign key with trigger, who's first?

I'd trying to create a ALBUM <- ALBUM_PHOTO -> PHOTO database model with MySQL.
and of course, I want to update these 3 tables synchronously, like when I insert into ALBUM_PHOTO, also insert into ALBUM and PHOTO with corresponding values.
But when I add triggers, the order of them made me confused and finally I got this method, like below:
-- --------------------------------------------------------
--
-- TABLE `user_album`
--
CREATE TABLE IF NOT EXISTS `user_album` (
`album_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`album_name` varchar(45) NOT NULL,
`cover_id` int(11) NOT NULL,
`numbers_of_photo` int(11) NOT NULL,
`album_desc` varchar(45) DEFAULT NULL,
`album_path` varchar(45) DEFAULT NULL,
`addtime` datetime NOT NULL,
PRIMARY KEY (`album_id`,`user_id`),
KEY `fk_album_user_id_idx` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
--
-- TRIGGER `user_album`
--
DROP TRIGGER IF EXISTS `tg_album_insert`;
DELIMITER //
CREATE TRIGGER `tg_album_insert` AFTER INSERT ON `user_album`
FOR EACH ROW BEGIN
UPDATE USER_ALBUM SET NUMBERS_OF_PHOTO = 0
WHERE ALBUM_ID = NEW.ALBUM_ID;
END
//
DELIMITER ;
DROP TRIGGER IF EXISTS `tg_album_update_then_delete`;
DELIMITER //
CREATE TRIGGER `tg_album_update_then_delete` AFTER UPDATE ON `user_album`
FOR EACH ROW BEGIN
DELETE FROM USER_ALBUM
WHERE ALBUM_ID = NEW.ALBUM_ID AND NEW.NUMBERS_OF_PHOTO <= 0;
END
//
DELIMITER ;
-- --------------------------------------------------------
--
-- TABLE `user_photo`
--
CREATE TABLE IF NOT EXISTS `user_photo` (
`photo_id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL,
`thumbnail_id` int(11) NOT NULL,
`photo_name` varchar(45) DEFAULT NULL,
`addtime` datetime NOT NULL,
`photo_path` varchar(45) NOT NULL,
PRIMARY KEY (`photo_id`),
KEY `fk_photo_user_id_idx` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
-- --------------------------------------------------------
--
-- TABLE `user_album_photo`
--
CREATE TABLE IF NOT EXISTS `user_album_photo` (
`photo_id` int(11) NOT NULL AUTO_INCREMENT,
`album_id` int(11) NOT NULL,
`user_id` int(11) NOT NULL,
`photo_name` varchar(45) DEFAULT NULL,
`desc` varchar(45) DEFAULT NULL,
`tag` varchar(45) DEFAULT NULL,
PRIMARY KEY (`photo_id`),
KEY `fk_album_photo_photo_id_idx` (`photo_id`),
KEY `fk_album_photo_album_id_idx` (`album_id`),
KEY `fk_album_photo_user_id_idx` (`user_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1 ;
--
-- TRIGGER `user_album_photo`
--
DROP TRIGGER IF EXISTS `tg_album_photo_delete`;
DELIMITER //
CREATE TRIGGER `tg_album_photo_delete` AFTER DELETE ON `user_album_photo`
FOR EACH ROW BEGIN
DELETE FROM USER_PHOTO WHERE PHOTO_ID = OLD.PHOTO_ID;
UPDATE USER_ALBUM SET NUMBERS_OF_PHOTO = NUMBERS_OF_PHOTO-1
WHERE ALBUM_ID=OLD.ALBUM_ID;
END
//
DELIMITER ;
DROP TRIGGER IF EXISTS `tg_album_photo_insert`;
DELIMITER //
CREATE TRIGGER `tg_album_photo_insert` AFTER INSERT ON `user_album_photo`
FOR EACH ROW BEGIN
IF NOT EXISTS (SELECT * FROM `user_album` WHERE ALBUM_ID = NEW.ALBUM_ID) THEN
INSERT INTO USER_ALBUM VALUES(NEW.ALBUM_ID, UEW.USER_ID);
ELSE
UPDATE USER_ALBUM SET NUMBERS_OF_PHOTO=NUMBERS_OF_PHOTO+1
WHERE ALBUM_ID = NEW.ALBUM_ID;
END IF;
INSERT INTO USER_PHOTO VALUES(NEW.PHOTO_ID, NEW.USER_ID);
END
//
DELIMITER ;
But now, the question is, I added foreign key constraint in USER_ALBUM_PHOTO TABLE, but when inserting a record, it is firstly inserted into USER_ALBUM_PHOTO when there isn't the corresponding record in the other 2 tables.
So, do I need to add the constraint into the other 2 tables instead of USER_ALBUM_PHOTO, maybe like PHOTO >- ALBUM_PHOTO <- ALBUM ?
Or there must be sth. wrong in my triggers.
Thx!