MySQL trigger - how to update specific row in another table - mysql

I have these two tables
**Table tb_data**
tb_id
timestamp
pagid
proid
status
(and many more)
**Table tb_units**
pag_id
pag_sn
user
latest_profile
latest_status
latest_feedback
latest_timestamp
Whenever a new row is created in tb_data, i would like some values updated in tb_units. In tb_units pag_id is unique and every number only exists once.
How do I trigger this, so the new values in tb_data are updated in tb_units? pagid equals pag_id and the corresponding values proid should update latest_profil, status should update latest_status, timestamp should update latest_timestamp
In the end I would like to end up with the latest pagid input to tb_data to be available in tb_units, since tb_data will contain multiple rows from the same pagid
I hvae tried several different aproaches, and have read a lot of examples, but I just don't get how these triggers work!
Latest example, that doesn't work:
CREATE TRIGGER update_units
AFTER INSERT ON tb_data
BEGIN
UPDATE tb_units
SET latest_profile = tb_data.9C,
latest_status = tb_data.91
WHERE pag_id = tb_data.86;
END

Not sure but something like this should work
CREATE TRIGGER update_units
AFTER INSERT ON tb_data
BEGIN
UPDATE tb_units
SET latest_profile = new.proid,
latest_status = new.status
WHERE pag_id = new.pagid;
END

Related

Trigger AFTER UPDATE for effected rows only

My Prestashop table ps_stock available has a column called quantity where the stock of the product is stored. This table is updated by an app, changing the values of the quantity column.
I need a trigger in that table. Every time the quantity of a product is changed I need to extract which products are effected on that table to insert them in another table
I have tried a trigger like this:
IF (OLD.quantity <> NEW.quantity)
THEN
INSERT IGNORE INTO ps_ebay_product_modified (id_ebay_product_modified,id_ebay_profile,id_product)
SELECT ps_ebay_product.id_ebay_product,id_ebay_profile,id_product
FROM ps_ebay_product INNER JOIN ps_stock_available
WHERE OLD.quantity <> NEW.quantity;
END IF
What I need is a selection of the products that have been changed.
This should work
CREATE TRIGGER mytrigger AFTER UPDATE ON ps_stock
FOR EACH ROW
BEGIN
-- do some stuff here
END;

MySQL trigger to insert date to row with unique matching ID

I need to write an SQL trigger to insert the date into a row of another table after an insert.
The data comes in as such:
A form is submitted to _OnsiteTable which includes a JobID, this JobID matches a current entry containing a JobID value in _JobTable. Upon insert of the data into _OnsiteTable I need a trigger that will insert the current date into a column called JobClosedDate in JobTable.
It needs to insert the date into the row that matches the JobID value entered in the form on _OnsiteTable.
I have this so far but I don't know how to compare the JobID values between tables and insert into the specific row.
CREATE TRIGGER UpdateClosedDate
AFTER INSERT on _OnsiteTable
BEGIN
Declare ClosedDate DATETIME;
SET ClosedDate = CURDATE();
CASE WHEN (ClosedDate) = ?
THEN INSERT INTO `_JobTable`( `JobClosedDate`)
VALUES
( ClosedDate);
END CASE;
END
Any help is greatly appreciated!
Complete query now working, thank you! As below:
CREATE TRIGGER UpdateClosedDate
AFTER INSERT on _OnsiteTable
BEGIN
Declare ClosedDate DATETIME;
SET ClosedDate = CURDATE();
UPDATE `_JobTable` SET `JobClosedDate` = ClosedDate WHERE `JobID` = new.JobID;
END
Since the problem was solved with the given comment I will add it here to reference for others with similar issues:
Since you want to Update a column ("insert a value into a column...") You just need to fix your trigger changing your current case statement to an update command as follow:
UPDATE `_JobTable`
SET `JobClosedDate` = ClosedDate
WHERE `JobID` = NEW.JobID;

Lookup data in one table and update another

I need a trigger that fires on update of a particular column in a table, and updates other columns using data from two other tables.
Table 1 is called STOCK_ITEMS
The columns concerned are all foreign keys
Column STOCKGROUP is FK for Table STOCK_GROUPS
Column STOCKGROUP2 is FK for Table STOCK_GROUP2S
Column X_STOCK_GROUP3 is FK for X_STOCK_GROUP3S
Table X_STOCK_GROUP3S contains the FKs of the other two stock group tables.
The idea is to make the first two columns dependent on the third, so that if the value of X_STOCK_GROUP3 changes, this trigger will set the values of STOCKGROUP and STOCKGROUP2 using the data from X_STOCK_GROUP3S
I tried this:
CREATE TRIGGER STOCKGROUP
ON [dbo].[STOCK_ITEMS]
FOR UPDATE
AS
IF UPDATE (X_STOCK_GROUP3)
set STOCKGROUP = STOCK_GROUPS.GROUPNO
PRINT 'AFTER UPDATE Trigger fired.'
GO
It does not work. It does not like my '=' sign. Or is there something else I'm missing (likely!!)
Any and all help appreciated.
Don' know if I understand what you want to do.
X_STOCK_GROUP3S contains some records like
(ID,STOCKGROUP,STOCKGROUP2)
(21,1000,300)
(22,2000,200)
(23,3000,100)
and STOCK_ITEMS contains records like
(ID,...,STOCKGROUP,STOCKGROUP2,X_STOCK_GROUP3)
If X_STOCK_GROUP3 of table STOCK_ITEMS is updated to 21 you want to set the values STOCKGROUP to 1000 and STOCKGROUP2 to 300.
Is this what you want to accomplish?
Then your code is missing some selection criteria.
I would try something like this
CREATE TRIGGER STOCKGROUP
ON [dbo].[STOCK_ITEMS]
FOR UPDATE
AS
SET NOCOUNT ON;
IF UPDATE (X_STOCK_GROUP3)
UPDATE STOCK_ITEMS SET STOCKGROUP = (
SELECT STOCKGROUP FROM X_STOCK_GROUP3S
WHERE STOCK_ITEMS.X_STOCK_GROUP3 = X_STOCK_GROUP3S.ID
),
STOCKGROUP2 = (
SELECT STOCKGROUP2 FROM X_STOCK_GROUP3S
WHERE STOCK_ITEMS.X_STOCK_GROUP3 = X_STOCK_GROUP3S.ID
)
WHERE ID IN (SELECT ID FROM deleted);
GO
OK, so here is the final, and successful, result:
Kudos credit: Sonny Dhaliwal - Support Consultant - Enprise Solutions. Thanks Sonny.
USE [MyDataBase]
GO
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TRIGGER [dbo].[X_SET_STOCK_GROUPS]
ON [dbo].[STOCK_ITEMS]
FOR UPDATE
AS
DECLARE #STOCKCODE VARCHAR(100),
#STOCKGROUP3 INTEGER,
#STOCKGROUP1 INTEGER,
#STOCKGROUP2 INTEGER
BEGIN
SELECT #STOCKCODE = STOCKCODE FROM inserted
SELECT #STOCKGROUP3 = X_STOCK_GROUP3 FROM inserted
SELECT #STOCKGROUP1 = (SELECT SECONDARY_GROUP FROM X_STOCK_GROUP3S
WHERE SEQNO = #STOCKGROUP3)
SELECT #STOCKGROUP2 = (SELECT PRIMARY_GROUP FROM X_STOCK_GROUP3S
WHERE SEQNO = #STOCKGROUP3)
BEGIN
UPDATE STOCK_ITEMS
SET STOCKGROUP = #STOCKGROUP1, STOCKGROUP2 = #STOCKGROUP2
WHERE STOCKCODE = #STOCKCODE
END
END
GO

Using and UPDATE Trigger to Modify the Row Being Updated

I have an employee table (em) that contains, among other things, a floor Id (fl_id) and room Id (rm_id). In certain circumstances (when em_loc_cnt = 0) I want to set the em record's fl_id and rm_id to null. Below is my code so far.
I am not sure how to refer to the fl_id & rm_id in the commented line. Will I run into issues because this trigger is being called as a result of the em record being updated and I am updating that same record in the trigger?
Suggestions?
IF EXISTS (SELECT * FROM [sysobjects] WHERE [name] = 'em_upd_self_serv_t' AND [type] = 'TR')
BEGIN
DROP TRIGGER [dbo].[em_upd_self_serv_t]
END
GO
CREATE TRIGGER [dbo].[em_upd_self_serv_t]
ON [dbo].[em]
AFTER UPDATE
AS
BEGIN
DECLARE #em_id VARCHAR(35),
#em_loc_cnt INT;
SET #em_id = (SELECT em_id FROM inserted);
SET #em_loc_cnt = (SELECT COUNT(*) FROM emlocs WHERE em_id = #em_id);
IF (#em_loc_cnt = 0)
BEGIN
-- I want to set the fl_id and the rm_id to NULL
END
END;
Your fundamental flaw is that you seem to expect the trigger to be fired once per row - this is NOT the case in SQL Server. Instead, the trigger fires once per statement, and the pseudo table Inserted might contain multiple rows.
Given that that table might contain multiple rows - which one do you expect will be selected here??
SET #em_id = (SELECT em_id FROM inserted);
It's undefined - you might get the values from arbitrary rows in Inserted.
You need to rewrite your entire trigger with the knowledge the Inserted WILL contain multiple rows! You need to work with set-based operations - don't expect just a single row in Inserted !
You need to change your code to something like this:
IF EXISTS (SELECT * FROM sys.triggers WHERE [name] = 'em_upd_self_serv_t')
DROP TRIGGER [dbo].[em_upd_self_serv_t]
GO
CREATE TRIGGER [dbo].[em_upd_self_serv_t]
ON [dbo].[em]
AFTER UPDATE
AS
UPDATE dbo.em
SET fl_id = NULL, rm_id = NULL
FROM Inserted i
WHERE em_id = i.em_id
AND NOT EXISTS (SELECT * FROM dbo.emlocs WHERE em_id = i.em_id)

Mysql: Toggle value of int field under two conditions for UPDATE query

What I'm looking to do is insert a record, then deactivate previous records with the same ID because they will no longer be in use. However, I'm looking to do this in the simplest way possible. Deleting the record really isn't an option.
Attempted order of operations:
Insert with active inUse value inUse = 1
Update the following records for the same ID that are no longer in use: inUse = 0
My first thought was to run this query:
UPDATE page_tags
SET inUse = IF(inUse = 1, 0, 1)
WHERE page_id = 23678459
AND tag_id NOT IN (10, 4);
The only problem with this query is that if it's run again, it will toggle all of those deactivated values back to 1. I need all of the tags for the specific ID to only toggle back if they are being targeted by the WHERE statement.
Sounds like a job for trigger. Something like will perhaps do (pseudocode)?
UPDATE for handling reuse of previuos tags:
Do your insert/update:
INSERT INTO ... ON DUPLICATE KEY UPDATE
Then use two triggers, one for inserts and one for updates.
CREATE TRIGGER tr_inuse_insert BEFORE INSERT ON page_tags
FOR EACH ROW BEGIN
UPDATE page_tags SET inuse=0 WHERE page_id = NEW.page_id;
END;
CREATE TRIGGER tr_inuse_update BEFORE UPDATE ON page_tags
FOR EACH ROW BEGIN
UPDATE page_tags SET inuse=0 WHERE page_id = NEW.page_id;
END;
#John P has a decent answer, however his answer requires the use of triggers. That to me seems to be more than needed to solve the problem at hand. The current working solution is:
Create an Unique Index on page_tags.page_id and page_tags.tag_id.
Update all rows where the *page_id = 234234*:
UPDATE page_tags SET inUse = 0 WHERE page_id = 234234
Insert tags:
INSERT INTO page_tags (page_id, tag_id, inUse) VALUES (234234, 49343, 1) ON DUPLICATE KEY UPDATE inUse = 1