Create Trigger : update table column by inserting data into another table rows - mysql

Please Help me to create triggers,
I have 2 tables of
data
+---------+------------+-------+-------+
| id | info_id | rate | qty | total |
+----+---------+------------+----------+
| 80 | 10 | 150 | 5 | 750 |
+----+---------+-------+-------+-------+
| 81 | 10 | 50 | 5 | 250 |
+--------------+-------+-------+-------+
info
+---------+---------------+------------+
| id | name | gtotal | dated |
+-----+--------+----------+------------+
| 10 | Hari | NULL | 2021-05-15 |
+---------+------------+---------------+
I want to create a trigger through phpmyadmin, as soon as data will be inserted, then info.gtotal will be updated by adding data.total from matched info_id from table name- data.
what will be the trigger if update on data happens too. I just want to create both triggers.
I am new with such, please help me. Any help is accepted.

You need to create two triggers one for insert and another for update.
CREATE TRIGGER `insert_trigger`
AFTER INSERT ON `data`
FOR EACH ROW
UPDATE info
SET gtotal = gtotal + new.total
WHERE id = new.info_id;
Here new.info_id will have the info_id value of newly insert record
CREATE TRIGGER `update_trigger`
AFTER UPDATE ON `data`
FOR EACH ROW
UPDATE info
SET gtotal = (gtotal - old.total) + new.total
WHERE id = new.info_id;
Here old.total will have the total value of record before updating. new.total is the total value after updation.
Since you haven't conveyed what to do after update I have added the logic of subtracting the total from old total and added the new total value. Change it as per your requirement.
You can also create these triggers using GUI in phpmyadmin. You have to select the triggers in the menu bar and add the trigger definition.

Related

How to preserve value of one column based on other column values?

I have a requirement wherein I will be getting records which I need to insert into a database (MariaDB 10.3) table wherein for each record I have 2 base values viz. name and amount and one processed value viz. action (imagine this action is something acted upon by user from UI).
+---------+--------+----------------+----------------+
| name | amount | action | created_at |
+---------+--------+----------------+----------------+
| Akshay | 1000 | processed | 2019-08-01 |
+---------+--------+----------------+----------------+
Now, what I want to achieve is when next time I receive a record with name and amount which already exist in the table, then populate action by automatic reference to the previous entry from this same table whose name and amount match.
And if name and amount combination does not exist in the table, then do not populate action.
Desired end result is depicted in structure below:
+---------+--------+----------------+----------------+
| name | amount | action | created_at |
+---------+--------+----------------+----------------+
| Akshay | 1000 | processed | 2019-08-04 |
| Akshay | 1001 | | 2019-08-03 |
| Saanvi | 1000 | | 2019-08-02 |
| Akshay | 1000 | processed | 2019-08-01 |
+---------+--------+----------------+----------------+
Any clues how can I achieve this functionality?
DROP PROCEDURE IF EXISTS db.SP_CREATE_VALUE;
CREATE PROCEDURE db.`SP_CREATE_VALUE`(IN `in_name` VARCHAR(50), IN `in_amount` INT)
BEGIN
DECLARE numAlreadyExists INT(11) DEFAULT 0;
DECLARE strExistingAction VARCHAR(20) DEFAULT "";
SET numAlreadyExists=(SELECT COUNT(*) FROM table_name WHERE name=in_name AND in_amount=in_amount);
IF (numAlreadyExists >0) THEN
SET strExistingAction=(SELECT action FROM table_name WHERE name=in_name AND in_amount=in_amount ORDER BY table_id DESC LIMIT 1);
END IF;
INSERT INTO table_name
name=in_name,amount=in_amount,action=strExistingAction;
END;
And then when you want to create a new record, simply...
CALL SP_CREATE_VALUE('Akshay',1000);
You can use window functions. For instance:
select name, amount,
max(action) over (partition by name, amount order by date) as action,
date
from t;

Mysql Trigger - Update table when insert another table

I have three tables:
Import Table:
import_id | import_date
-------------------------
1 | 2019/07/29
2 | 2019/07/28
ImportItem Table:
import_id | product_id | quantity
-------------------------------------
1 | 1 | 50
1 | 2 | 60
1 | 3 | 20
Product Table:
product_id | quantity
---------------------------
1 | 10
2 | 5
3 | 15
I want to create a trigger update quantity in product table when insert ImportItem table.
Any help much appreciated! Thanks very much!
If you create a trigger in your table import_item that will update your table product after each import_item INSERT you can do this :
CREATE TRIGGER trigger_name
AFTER INSERT
ON import_item FOR EACH ROW
BEGIN
UPDATE product SET quantity = NEW.quantity WHERE product_id = NEW.product_id;
END
Here is some documentation about the trigger key words NEW and OLD : documentation
When you are in a BEFORE/AFTER INSERT trigger, you can use NEW.field to get the value of the new field you just inserted.
Now if you are in a BEFORE/AFTER UPDATE trigger, you can use NEW.field to get the value of the field AFTER the update and OLD.value to get the value of the field BEFORE the update.
And the last, if you are in a BEFORE/AFTER DELETE trigger , you can use OLD.field to get the value fo the field before the delete.
Is it what you are looking for ?

Use ON DUPLICATE KEY UPDATE to update row with MySQL

I've the following table structure:
Table ___Availabilities :
|--------|------------|------------|------------|
| AVA_Id | AVA_RoomId | AVA_Date | AVA_Status |
|--------|------------|------------|------------|
| 1 | 47 | 2019-03-11 | NoData |
| 2 | 48 | 2019-03-22 | Book |
| 3 | 48 | 2019-03-23 | Book |
|--------|------------|------------|------------|
I want to UPDATE the AVA_Status only if AVA_RoomId and AVA_Date are know in a row of the table. If not, INSERT a new row.
So my query is this one:
INSERT INTO ___Availabilities
(AVA_Id, AVA_RoomId, AVA_Date, AVA_Status)
VALUES('', '103', '2019-04-04', 'Open')
ON DUPLICATE KEY UPDATE
`AVA_RoomId`='47',
`AVA_Date`='2019-03-11'
But it doesn't work as it added a new row whereas it should update the row where AVA_RoomId = 47 and AVA_Date = 2019-03-11.
Why my query is not working please ?
Thanks.
Assuming there is a UNIQUE INDEX(AVA_RoomId, AVA_Date)
You might want to update the AVA_Status when the combination of room and date already exists:
INSERT INTO ___Availabilities
(`AVA_RoomId`, `AVA_Date`, `AVA_Status`)
VALUES('103', '2019-04-04', 'Open')
ON DUPLICATE KEY UPDATE
`AVA_Status` = VALUES(`AVA_Status`),
As #Barmar already explained, if not already done, you can still add an index after table creation:
ALTER TABLE `___Availabilities`
ADD UNIQUE INDEX `uq_room_date` (`AVA_RoomId`, `AVA_Date`)
;

How to apply automated query after each insert with condition?

If I have a table like that:
id | name | points
------------------
1 | Hala | 50
2 | Asa | 60
3 | Hala | 1000
How can I apply automated query that applied after each insert but with condition
like this query but only to apply on the latest item after it is inserted
update points set points = points / 10 where name = 'Hala';
Try to create a trigger like this
CREATE TRIGGER MyTrigger AFTER INSERT ON MyTable
FOR EACH ROW BEGIN
SET NEW.points = NEW.points/10;
END

MySQL: Copy data from TableA:FieldA to TableB:FieldB matching common UID field

I didn't see this exact question asked. Most people seem to want to sync. I just need a one-time copy.
MySQL version is 5.5.35.
In my MySQL database I need to one-time copy data from TableA:FieldA to TableB:FieldB while matching a common UID field — TableA:UID and TableB:UID are the related fields.
More specifically I am copying Employee ID from one table to a different field in another table, and both tables have Contact ID in common. So obviously I need TableA:UID=1's Employee Number to appear in TableB on the correct row where TableB:UID=1.
Thanks.
UPDATED: Tested the solution, got an error 1442
UPDATE civicrm_value_member_fields_1
SET civicrm_value_member_fields_1.aft_id_43 =
(SELECT civicrm_contact.external_identifier FROM civicrm_contact
WHERE civicrm_contact.id = civicrm_value_member_fields_1.entity_id)
alt version of the above:
UPDATE `civicrm_value_member_fields_1`
SET `aft_id_43` =
(SELECT `external_identifier` FROM `civicrm_contact`
WHERE `id` = `entity_id`)
both error 1442:
#1442 - Can't update table 'civicrm_contact' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The following example should help.
create table A(id int,cid int);
create table B(id int,cid int);
insert into A values(6,1);
insert into A values(7,2);
insert into A values(8,3);
insert into A values(9,4);
insert into B(cid) values(1);
insert into B(cid) values(3);
insert into B(cid) values(4);
Table A
| ID | CID |
|----|-----|
| 6 | 1 |
| 7 | 2 |
| 8 | 3 |
| 9 | 4 |
Table B
| ID | CID |
|--------|-----|
| (null) | 1 |
| (null) | 3 |
| (null) | 4 |
The UPDATE query will update B's id field referring A's id field.
update B set B.id = (select A.id from A where A.cid = B.cid);
Table B
| ID | CID |
|----|-----|
| 6 | 1 |
| 8 | 3 |
| 9 | 4 |
The error can be sidestepped by first creating a temporary table - it will have all the data you need but not have the functions/triggers that impede the step.
Also, once the table is set then a JOIN statement is a more efficient representation of the action and should run more quickly as well.
CREATE TEMPORARY TABLE contact_dupe SELECT id, external_identifier FROM civicrm_contact;
UPDATE civicrm_value_member_fields_1 AS cs
JOIN contact_dupe AS cd ON cd.id=cs.entity_id
SET cs.aft_id_43=cc.external_identifier;