How can I access the the INSERTED table's values in a trigger?
For example:
INSERT INTO sales (sku, qty)
VALUES
(1001, 5), //I need these values in the trigger
(1002, 1)
...
This is my trigger:
DELIMITER $$
CREATE TRIGGER after_sales_insert
AFTER INSERT ON sales
FOR EACH ROW BEGIN
UPDATE products
SET NEW.qty = OLD.qty - INSERTED.qty
WHERE sku = INSERTED.sku;
END;
$$
DELIMITER;
Note that sales.sku is a foreign key for the products table.
SQL Server has the INSERTED keyword, which doesn't seem to work for MySQL.
Answer:
NEW.qty references the qty on the table that the trigger is set on, not the table that is being updated.
CREATE TRIGGER after_sales_insert
AFTER INSERT ON sales
FOR EACH ROW BEGIN
UPDATE products
SET qty = qty - NEW.qty
WHERE sku = NEW.sku;
END;
Given:
INSERT INTO sales (sku, qty)
VALUES
(1001, 5), //I need these values in the trigger
(1002, 1)
...
I believe you want this:
CREATE TRIGGER after_sales_insert AFTER INSERT ON sales
FOR EACH ROW BEGIN
UPDATE products
SET qty = qty - NEW.qty
WHERE sku = NEW.sku;
END;
References:
MySQL 8: 24.3.1 Trigger Syntax and Examples
How to program a MySQL trigger to insert row into another table?
How does "for each row" work in triggers in mysql?
Related
My tables:
Orders Products
Id(PK) |Quantity | Date | ProdIdFK |OrdFK(ref CustomerID) ProdID(PK) | Quantity | Name
and customer table.
I have to make an order using trigger so i do:
INSERT into Orders(Id, Quantity, Date, ProdIDFK, OrdFK)
values(3, 2, '2020/01/27', 15, 2);
CREATE TRIGGER QuantityUpdate
AFTER INSERT
ON Orders FOR EACH ROW
BEGIN
UPDATE Products
SET products.Quantity = Products.Quantity - New.Quantity
WHERE products.ProdID = New.ProdID
END$$
DELIMITER ;
But just nothing happening, it shows the old quantity and doesnt change. I tried to put INSERT after BEGIN(i dunno what is correct one) and also nothing. What is correct query for this?
Your trigger code looks OK - apart, maybe, for a glitch in the column name spotted by Gordon Linoff.
However, if you want it to fire on the INSERT statement that is showed in your script, you need to create it first, then INSERT.
CREATE TRIGGER QuantityUpdate
AFTER INSERT ON Orders FOR EACH ROW
BEGIN
...
END$$
DELIMITER ;
INSERT into Orders(Id, Quantity, Date, ProdIDFK, OrdFK)
VALUES(3, 2, '2020-01-27', 15, 2);
Once the trigger is created, it fires for every order inserted. It has no way, however, to take in account inserts that happened before its creation.
At the very least, the syntax is wrong in either the INSERT or the trigger, because one is using ProdIdfk and the other ProdId.
If the first is the correct name, then the trigger should be:
UPDATE Products p
SET p.Quantity = p.Quantity - New.Quantity
WHERE p.ProdID = New.ProdIDFK;
I have a mysql table where I use this query:
INSERT INTO `stats` (`id`, `shop`, `price`, `timestamp`)
VALUES (NULL, '$shop', '$price', 'timestamp') ON DUPLICATE KEY UPDATE price='$price'
The shop column is unique. "Id" = primary key. The timestamp column is updated by mysql: on update CURRENT_TIMESTAMP
Data in the dB:
row: id=1, shop=viacom, price=5, timestamp=1524183480
Case 1: Row to be inserted: shop=viacom, price=6
Result: The existing row is updated
Case 2: Row to be inserted: shop=viacom, price=5 (<-- price has NOT changed)
Result: The existing row is NOT updated
I would like to get case 2 working. I can handle it with php-code, but I'd rather let Mysql do that job. Any ideas? (I tried adding a Where Clause like $shop=shop)
Since the shop column is a UNIQUE key, you can remove the id column and use the below.
replace into stats (shop, price) values ('$shop', '$price')
If shop already exists, then the price is updated. Else a new shop will be inserted. Is this what you want?
Try to update the timestamp column manually:
INSERT INTO `stats` (`shop`, `price`) VALUES ('$shop', '$price')
ON DUPLICATE KEY UPDATE price='$price', timestamp = NOW();
=========
Option #2:
If you want to do it in MySQL, create stored procedure and call the stored procedure from PHP code.
CREATE PROCEDURE `createOrUpdatePrice` (ex_shop varchar(255),ex_price int(11))
BEGIN
declare occures tinyint(1);
SELECT COUNT(`shop`) into occures from `stats` WHERE shop = ex_shop;
IF occures = 0 Then
INSERT INTO `stats` (`id`, `shop`, `price`) VALUES (NULL, ex_shop, ex_price);
ELSE
UPDATE `stats` SET price = ex_price where shop = ex_shop;
END IF;
END
I am running the following procedure in mysql:
create procedure addSavingAccount(id int(10), account_number varchar(10))
begin
insert into saving values(id,'savings', account_number, 0);
end //
However, when I try to call it, it gives me this error:
mysql> call addSavingAccount(103, 'B505');
ERROR 1136 (21S01): Column count doesn't match value count at row 1
I checked on anything that could be linked to it, including triggers. But everything seems like it should be working. Here is my list of triggers:
create trigger balance_change_saving after update on saving for each row
begin
if old.balance != new.balance
then
insert into balance_update_history values(null, 'saving', new.account_number, old.balance, new.balance,
(SELECT NOW()), (select USER()));
end if;
end//
create trigger balance_insert_saving after insert on saving for each row
begin
insert into balance_update_history values(null, 'saving', new.account_number, 0, new.balance, (select now()),
(select user()));
end //
create trigger balance_delete_saving after delete on saving for each row
begin
insert into balance_update_history values(null, null, null, old.balance, null,
(SELECT NOW()), (select USER()));
end //
And here is where I define the table:
create table if not exists saving(account_number varchar(10) , customer_id int(10), balance decimal(8,2), primary key(account_number));
I'd just really like to to figure this out.
There are three columns based on your table create statement, not four. (what is the last 0 in that insert?)
Also, in the procedure, it appears that your insert values are out-of-order relative to the table creation order? So you can either rearrange the insert values to match the table, OR specify the columns with the insert.
I have a table called history with the fields id, g.id, date, value. I want to put a trigger that will update the table when a new row is inserted and divide the number inserted in the value field by 2.
I have been trying for hours with no luck, any help would be appreciated.
for eg, after
INSERT INTO `online_game_shop`.`history`
(`id`, `gameID`, `dateofPurchase`, `Value`)
VALUES ('1001', '101', '2014-02-22', '10');
so the trigger will automatically divide 10 by 2 and update the field with result.
CREATE TRIGGER pointstovalue
AFTER INSERT ON history
FOR EACH ROW
BEGIN
UPDATE history
SET value = new.value/2
WHERE history.id = NEW.id
END;
You want a before insert trigger:
CREATE TRIGGER pointstovalue
BEFORE INSERT ON history
FOR EACH ROW
BEGIN
set new.value = new.value/2;
END;
I have two tables:table1 and rating
table1(id,name,category)
rating (cid,rating,total_rating,total_rates,photoID)
and now when i insert data into table1 i want to set all data in table rating at zero for that specific photoID from table1, but i dont know how..can someone help me?
You can use LAST_INSERT_ID() to retrieve the ID you just inserted. For example, assuming PhotoID is the relation between table1 and rating:
insert table1 (name,category) values ('waterfall 2', 'nature');
insert rating (rating,total_rating,total_rates,photoID) values
(0, 0, 0, last_insert_id());
I'd rather create a STORED PROCEDURE to make a single call from application. Assuming that you want to INSERT a record on table rating for every insert on table1 and that ID on table1 is set as AUTO_INCREMENT.
DELIMITER $$
CREATE PROCEDURE procedureName
(
IN _name VARCHAR(25),
IN _category VARCHAR(25)
)
BEGIN
INSERT INTO table1 (name, category)
VALUES (_name, _category);
SET #last_ID := LAST_INSERT_ID();
INSERT INTO rating (cid, rating, total_rating, total_rates, photoID)
VALUES (#last_ID, 0,0,0,0);
END $$
DELIMITER ;
and call the procedure,
CALL procedureName('nameHere','categoryHere')
You can use MySql triggers http://dev.mysql.com/doc/refman/5.0/en/trigger-syntax.html:
CREATE TRIGGER ins_rating AFTER INSERT ON table1
FOR EACH ROW
BEGIN
INSERT INTO rating (cid,rating,total_rating,total_rates,photoID)
VALUES( NEW.ID ,0,0,0,null)
END;
If you want to insert data into TABLE1 and delete it from TABLE2, you can write below listed query:
mysql_query("DELETE * FROM table2");