Wanting to CONCAT two columns to make a new ID, as per the image.
Desired result
The Trigger statement I have is: And I have tried Trigger INSERT and UPDATE events.
Trigger statement
SET new.img_url_id = CONCAT(new.img_metadata_id, new.mag_name_id)
The Trigger statement returns values in the 'mag_name_id' field (10). The Trigger has to happen after field 'img_metadata_id' is inserted because 'img_metadata_id' is auto-incremented, and after 'mag_name_id' is inserted, it's pulled from another table. Changing the Trigger time to After, PHPMyAdmin gives an error. Do I need to do a Procedure?
Thanks.
Related
I am trying to create a trigger to simultaneously update a different table than the one I have updated, with the same data.
I have two different database with the same tables and i'm trying to sync them, when i insert, update or delete data from one, i want to do automaticaly the same to the other table, with triggers.
This is the trigger code:
CREATE DEFINER=`Ivan_test`#`%` TRIGGER `Prueba_Ivan`.`mag_articulos_PI_AFTER_UPDATE` AFTER UPDATE ON `mag_articulos_PI` FOR EACH ROW
BEGIN
IF OLD.Prueba_Ivan.mag_articulos_PI NOT IN (SELECT * FROM ivan_test.mag_articulos_IT) THEN
INSERT INTO ivan_test.mag_articulos_IT
VALUES (new.xempresa_id, new.xarticulo_id, new.xcategoria_id, new.xvisible_web, new.xnovedad,new.xpromocion,new.ximagen_prelim,new.ximagen_amp,new.xtexto1,new.xtexto2,new.xtexto3,new.xtexto4,new.xtexto5);
ELSE
UPDATE ivan_test.mag_articulos_IT SET OLD.ivan_test.mag_articulos_IT = NEW.Prueba_Ivan.mag_articulos_PI;
END IF;
END
but I have this error:
Error Code: 1109. Unknown table 'OLD.Prueba_Ivan' in IN/ALL/ANY subquery
Can someone help me to find the mistake?
Thank you!!
OLD.Prueba_Ivan.mag_articulos_PI
OLD is an alias to the triggered row. Your trigger applies to Prueba_Ivan, which means that OLD and NEW are representing your Prueba_Ivan record before the change, and after it, respectively. This means that when you intend to reference mag_articulos_PI, you will need to do it via OLD.mag_articulos_PI, so remove the tablename from that expression.
OLD.ivan_test.mag_articulos_IT
As mentioned in the previous section, here OLD is an alter-ego of the updated Prueba_Ivan record, you do not need it in order to reference ivan_test.
Further explanation
An expression of the form of
a.b.c
reads as follows:
In database a, table b, column c. When you do something of the like of
OLD.t.c
it reads: In the OLD database, table t, column c.
I have a table on a mysql 5.7 db, containing say athletes with their mean, max, avg times in a specific sport. I have another table that lists some calculated statistics based on those values.
I managed to do the calculcations that end up on the second using stored procedures. I use as input parameter to the stored procedure the athlete's name.
So when in the first table, an athlete is inserted (with his/her avg/min/max times) or his/her values are updated and I run the stored procedure, the later updates the statistics table.
My question is how to achieve the same result with triggers?
I guess it is feasible/easy to update the entire table on each insert or update of the first table. What would be more efficient performance-wise, would be on each :
INSERT into table1 values (..) where athlete_name="John Do"
(...)
ON DUPLICATE KEY UPDATE (...)
Run a trigger in the pseudocode form :
INSERT into statistics_table values (..) where athlete_name="John Do"
ON DUPLICATE KEY UPDATE (...)
How can the the athlete_name="John Do" be passed to the trigger dynamically, to avoid update the entire statistics table?
You cannot pass any parameters to a trigger and the insert statement does not support the where clause either.
Having said this, a trigger can pick up the user's name from the record being inserted / updated / deleted using NEW.athlete_name or OLD.athlete_name (whichever is required) and use that to call a stored procedure:
Within the trigger body, the OLD and NEW keywords enable you to access
columns in the rows affected by a trigger. OLD and NEW are MySQL
extensions to triggers; they are not case-sensitive.
In an INSERT trigger, only NEW.col_name can be used; there is no old
row. In a DELETE trigger, only OLD.col_name can be used; there is no
new row. In an UPDATE trigger, you can use OLD.col_name to refer to
the columns of a row before it is updated and NEW.col_name to refer to
the columns of the row after it is updated.
A column named with OLD is read only. You can refer to it (if you have
the SELECT privilege), but not modify it. You can refer to a column
named with NEW if you have the SELECT privilege for it. In a BEFORE
trigger, you can also change its value with SET NEW.col_name = value
if you have the UPDATE privilege for it. This means you can use a
trigger to modify the values to be inserted into a new row or used to
update a row. (Such a SET statement has no effect in an AFTER trigger
because the row change will have already occurred.)
You can create triggers that fire after each insert or update on the parent table (athletes). Within each trigger, you can access the value of column athlete_name on the record that was just created or changed, and then invoke your stored procedure using CALL().
Here is a code sample for such an INSERT trigger :
CREATE TRIGGER athletes_upd AFTER INSERT ON athletes
FOR EACH ROW
BEGIN
CALL my_procedure(NEW.athlete_name);
END;
UPDATE trigger :
CREATE TRIGGER athletes_upd AFTER UPDATE ON athletes
FOR EACH ROW
BEGIN
CALL my_procedure(NEW.athlete_name); -- or maybe OLD.athlete_name ?
END;
Am populating a table using a trigger after an insert event occurs on another table and that worked fine. However i then noticed that the trigger would still insert a new row for existing records. To fix this, I want to create the trigger again but this time it would only fire if a condition is met...but not having previously used triggers in the past am getting a syntax error and not able to identify what am doing wrong. Kindly have a look and help me fix this
CREATE TRIGGER `students_gen_insert`
AFTER INSERT ON `students` FOR EACH ROW
BEGIN
INSERT INTO records (student_id, subject_id)
SELECT new.student_id, subjects.subject_id
FROM subjects
WHERE category = new.class;
END;
Am currently using MySql 5.6.17 version.
It is generally not a good idea to SELECT from the table the trigger is on, and forbidden to UPDATE or INSERT (not that you are doing those). Assuming you are trying to get the values for the row just inserted, the first SET ... SELECT you have is needless; just use NEW.fieldname to get the fields of the inserted row.
The second SET ... SELECT and following condition are a bit confusing. If referential integrity is being maintained, I would think it would be impossible for the records table to refer to that particular student_id of the students table at the point the trigger is executed. Perhaps this was to avoid the duplicate inserts from the trigger's previous code? If so, it might help for you to post that so we can pinpoint the actual source of redundant inserts.
I want to count rows created/inside (dont know what it is called) a trigger.
like i have a trigger :
CREATE
DEFINER=`root`#`localhost`
TRIGGER `mydb`.`tn_air_staff_leave_application`
AFTER INSERT ON `mydb`.`staff_leave_application`
FOR EACH ROW
BEGIN
----
----
----
END$$
and want to know how many rows trigger is going to create, I need this value inside trigger:
set #newrows:= (select count(*) from tn_air_staff_leave_application);
is it possible?? if not any other solution out there???
A trigger is a purely passive piece of code which is executed before or after a row is inserted, updated or deleted from a table in your database.
The trigger can not be executed actively anc thus does not have a return value you can read.
What you can do is to let your trigger write a value into another table or into a session variable which then can be queried for in an extra query.
You can not store a whole result row or a result set of several rows into a session variable like you are trying in your example.
In MySQL the trigger is always executed FOR EACH ROW, means within the trigger you will only look at one row, not at several.
EDIT:
Actually your example query returns a single value, so this would work. (would deliver the amount of total records in your tn_air_staff_leave_application table into the local session variable #newrows)
For more specific help you would need to be more specific on what you're trying to do
When I insert data in db I have to compare the current record with the previous one. If neccassary, some values of the current record needs to be modified.
I've tried some pieces of SQL like below, but all give SQL errors. This one gives me an error says that I select more than 1 records.
DELIMITER $$
CREATE
TRIGGER set_moment_display
BEFORE INSERT ON data
FOR EACH ROW
BEGIN
DECLARE moment DATETIME;
SELECT press_moment_1 INTO moment FROM data LIMIT 1;
IF moment > NEW.press_moment_1 THEN SET NEW.press_moment_1 = moment;
END IF;
END$$
DELIMITER ;
How do I achieve what I've described above.
The problem here is that, since a SQL database has no implicit concept of row ordering (you supply the ordering criteria on every query), there is no "previous" row for the trigger to look at. The "previously inserted row" has no meaning in the context of an insert trigger.
Suppose for a moment that it did and there were several processes inserting rows in the table. When the trigger fired for process #1's insert, which row is the "previous" row? The one previously inserted by process #1? Suppose the chronologically "most recent" row was actually inserted by process #3?
If you need to do this it cannot be done in a trigger unless you can use a know key value to identify the row you understand as "most recent". Otherwise it must be handled in the application that is doing the inserts.
You can use the alias "OLD."
You can refer to columns in the subject table
(the table associated with the trigger) by using the aliases OLD and NEW.
OLD.col_name refers to a column of an existing row before
it is updated or deleted. NEW.col_name refers to the column
of a new row to be inserted or an existing row after it is updated
UPDATE
Jim Garrison properly pointed up to me the mistake, "BEFORE INSERT" doesn't have "OLD." values, this alias works only for UPDATE and DELETE.