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;
Related
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?
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
suppose for the table student if insert query is executed as INSERT INTO student(id,name) VALUES (1,'sumit');.Just after insertion of the row I want the recently inserted row's name field value to be capitalised using trigger.I searched for it every where but couldn't get working code,please some body help?
You can write the after insert and update trigger on table.
CREATE TRIGGER lcase_insert BEFORE INSERT ON my_table FOR EACH ROW
SET NEW.name = LOWER(NEW.name);
CREATE TRIGGER lcase_update BEFORE UPDATE ON my_table FOR EACH ROW
SET NEW.name = LOWER(NEW.name);
here NEW.name is your name inserted in table.
Based on my previous post found here im able to insert the values to the 2nd table when the status on first table changes, but it keeps adding indiscriminately, i need to check if the submit_id has already been inserted into the 2nd table and then update the fields not insert it gain, how would i do that check before the trigger is executed?
Because the new.status and old.status refer to the row being edited not the row on table it's being inserted into, how can i compare that and insert or update if it already exists,
Thanks
You can use INSERT INTO ... ON DUPLICATE KEY UPDATE syntax for that
If order for it to work properly you have to have a UNIQUE constraint on submitId column in your second table (let's call it students).
ALTER TABLE students ADD UNIQUE (submitId);
Now an improved version of a trigger
DELIMITER $$
CREATE TRIGGER tg_au_submissions
AFTER UPDATE ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
INSERT INTO students (submitId, studentName, submitDate, contacts, email)
VALUES (NEW.submitId, NEW.studentName, NEW.submitDate, NEW.contacts, NEW.email)
ON DUPLICATE KEY UPDATE
studentName = VALUES(studentName),
submitDate = VALUES(submitDate),
contacts = VALUES(contacts),
email = VALUES(email);
END IF;
END$$
DELIMITER ;
Here is SQLFiddle demo
I have to make two insert into like this:
INSERT INTO CONVERSATION (issue,...) VALUES ('Presentation',...);
INSERT INTO CONVERSATIONMESSAGES VALUES (ConversationId, 'Hello everybody',...);
In the first table the only PK is an autonumeric field (ConversationId) and later I have to know this autonumeric field to insert in the second table.
is there any way to do this? Something like do a select * when Im doing the first Insert to know it for the second Insert?
Thank you very much, I hope I explained correctly.
you could use LAST_INSERT_ID() to insert the last generated autoincremented on the table, eg
INSERT INTO CONVERSATION (issue,...) VALUES ('Presentation',...);
INSERT INTO CONVERSATIONMESSAGES VALUES (LAST_INSERT_ID(), 'Hello everybody',..);
LAST_INSERT_ID()
but this sometimes fail if you have concurrent INSERTs.
Try creating a stored procedure for this,
DELIMITER $$
CREATE PROCEDURE ProcNAME(...PARAMETERS HERE...)
BEGIN
INSERT INTO CONVERSATION (issue,...) VALUES ('Presentation',...);
SET #lstID = (SELECT MAX(ConversationId) FROM CONVERSATION);
INSERT INTO CONVERSATIONMESSAGES VALUES (#lstID, 'Hello..',..);
END
DELIMITER ;
declare #retVal as int
INSERT INTO CONVERSATION (issue,...) VALUES ('Presentation',...);
#retval=SELECT SCOPE_IDENTITY();
INSERT INTO CONVERSATIONMESSAGES VALUES (ConversationId, 'Hello everybody',...);
you will get last inserted row numberic value in #revVal to be used in other table