Create a table in a trigger and compare it - mysql

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

Related

Update inventory after transaction

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',
sell_price float,
`condition1` varchar(45) NOT NULL,
`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 `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`)
);
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`)
);
I have those tables and my objective is after i update transactions to completed it goes to my inventory table and update the stock. The items that it should update are the items that i choose in order items.
For now i have this peace of code but its not working ...
delimiter $
create trigger update_stock
after update on `transaction`
for each row
begin
if new.`status` = 'Completed' THEN
update inventory
set inventory.stock = inventory.stock - new.quantity
where inventory.id_product = new.id_product;
end if;
End $$
delimiter ;
Edited trigger:
delimiter $$
CREATE TRIGGER trigg1 after update on `transaction` for each row
BEGIN
UPDATE `inventory`
SET stock = (SELECT stock - new.quantity FROM order_item WHERE order_item.id_product = inventory.id_product limit 1);
end $$
delimiter ;
You seem to need an extra join to get the quantity from order_item:
update inventory i join
order_item oi
using (id_product)
set i.stock = i.stock - oi.quantity
where oi.id_order = new.id_order;

Error Code: 1109. Unknown table 'evrz.account' in field list

I am trying to create a trigger, but I get this error:
Error Code: 1109. Unknown table 'evrz.account' in field list
I tried to execute this:
INSERT INTO `record` (`record`.account_id) VALUES (289688082)
This is my trigger:
CREATE DEFINER=`root`#`localhost` TRIGGER `evrz`.`record_BEFORE_INSERT` BEFORE INSERT ON `record` FOR EACH ROW
BEGIN
IF `evrz`.`account`.`status` ='OUT' in (
SELECT `evrz`.`account`.`status`
FROM `evrz`.`account`
WHERE (account_id = NEW.account_id)
)THEN
UPDATE `evrz`.`account` SET `evrz`.`account`.`status` = 'IN' WHERE (`evrz`.`account`.`account_id` = NEW.account_id);
END IF;
IF `evrz`.`account`.`status` ='IN' in (
SELECT `evrz`.`account`.`status`
FROM `evrz`.`account`
WHERE (account_id = NEW.account_id)
)THEN
UPDATE `evrz`.`account` SET `status` = 'OUT' WHERE (`evrz`.`account`.`account_id` = NEW.account_id);
END IF;
END
These are my tables:
CREATE TABLE `employee` (
`employee_id` int(10) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`lastname` varchar(45) NOT NULL,
`address` varchar(45) NOT NULL,
`phone` varchar(45) NOT NULL,
`mail` varchar(45) NOT NULL,
`created_at` TIMESTAMP(0) NOT NULL DEFAULT 'CURRENT_TIMESTAMP()',
PRIMARY KEY (`employee_id`)
);
CREATE TABLE `account` (
`account_id` int(10) NOT NULL AUTO_INCREMENT,
`status` enum('IN','OUT') NOT NULL DEFAULT ''OUT'',
`employee_id` int(10) NOT NULL UNIQUE,
PRIMARY KEY (`account_id`)
);
CREATE TABLE `record` (
`record_id` int(10) NOT NULL AUTO_INCREMENT,
`account_id` int(10) NOT NULL,
`creted_at` TIMESTAMP(0) NOT NULL DEFAULT 'CURRENT_TIMESTAMP()',
PRIMARY KEY (`record_id`)
);
ALTER TABLE `account` ADD CONSTRAINT `account_fk0` FOREIGN KEY (`employee_id`) REFERENCES `employee`(`employee_id`);
ALTER TABLE `record` ADD CONSTRAINT `record_fk0` FOREIGN KEY (`account_id`) REFERENCES `account`(`account_id`);
I am trying to make that when an employee logs in to a database, his stsus will be changed.
The IF statement can only refer to the row that's being inserted, using NEW.columnName to refer to a column in the new row.
When you're updating another table, use the IF function (or a CASE expression) in the value, and it can refer to the existing value in the row being updated.
CREATE DEFINER=`root`#`localhost` TRIGGER `evrz`.`record_BEFORE_INSERT` BEFORE INSERT ON `record` FOR EACH ROW
BEGIN
UPDATE evrz.account
SET status = IF(status = 'OUT', 'IN', 'OUT')
WHERE account_id = NEW.account_id;
END

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.

Tiggers , before inserted trigger?

I have two tables , table (files) and table (Hashes) i want to create a procedure that inserts new (file) wich will add a ( Hash ) if not exists and then inserts its ( ID ) in the ( files) table , if exists select the (ID) and insert it , and i also must use ( before insert on files trigger ) i ried but it either gives me an CONSTRAINT error OR Insert in hash and no file inserted.
CREATE TABLE `Hashes` (
`ID` int(255) unsigned NOT NULL AUTO_INCREMENT,
`Hash` varchar(255) NOT NULL,
`Counter` int(255) NOT NULL DEFAULT '1',
PRIMARY KEY (`ID`),
UNIQUE KEY `Hash` (`Hash`)
)
and
CREATE TABLE `Files` (
`ID` int(255) unsigned NOT NULL AUTO_INCREMENT,
`Name` varchar(255) NOT NULL,
`ParentPath` varchar(255) DEFAULT NULL,
`Size` double NOT NULL,
`Date` date NOT NULL,
`ParentID` int(255) unsigned NOT NULL DEFAULT '0',
`HashID` int(255) unsigned DEFAULT NULL,
PRIMARY KEY (`ID`),
KEY `fk_Hash_ID` (`HashID`),
CONSTRAINT `fk_Hash_ID` FOREIGN KEY (`HashID`) REFERENCES `hashes` (`ID`)
)
////////
CREATE PROCEDURE SP_Files_Insert
(
parmName VARCHAR(255),
parmParentPath VARCHAR(255),
parmSize DOUBLE,
parmDate DATE,
parmParentID INTEGER,
parmHash VARCHAR(255)
)
BEGIN
INSERT INTO Files( Name, ParentPath, Size, Date, ParentID, HashID)
VALUES(parmName, parmParentPath, parmSize, parmDate, parmParentID, LAST_INSERT_ID());
END;
////////////
CREATE TRIGGER TR_Insert_File BEFORE INSERT ON Files
FOR EACH ROW
BEGIN
INSERT INTO Hash( Hash, Counter)
VALUE( parmHash, 1)
ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID), Counter = Counter + 1;
END;
use delimiter in your trigger like below that will work for you
delimiter \\
CREATE TRIGGER TR_Insert_File BEFORE INSERT ON Files
FOR EACH ROW
BEGIN
INSERT INTO Hash( Hash, Counter)
VALUE( parmHash, 1)
ON DUPLICATE KEY UPDATE ID = LAST_INSERT_ID(ID), Counter = Counter + 1;
END\\
delimiter ;

Update row after insert from a another table

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.