I'm trying to create a trigger that will do two things:
Copy everything from a row in table X to a row in table Y before an UPDATE is done
Copy one column from a row in table X to a row in table Y after the UPDATE from no. 1 is done
This is what I have until now:
delimiter //
create trigger log
before update on opnaar
for each ROW
begin
set #a = opnaar.id;
set #c = opnaar.initials;
set #d = opnaar.revised;
set #f = opnaar.course;
insert into log(id,init_old,date_old,date_new,course) values (#a,#c,#d,NOW(),#f);
end;
after update on opnaar
for each ROW
begin
set #e = opnaar.initials;
insert into log(init_new) values (#e);
end;
But I figured it's not possible to add just one value to an already existing row in a table. At least, not the way I am trying to do this. Should I place the after update within the first action?
Example: I have this content:
I want to copy course, revised, initials and id to another table. That's what my first action should do.
After a teacher has updated something in that table, the NEW initials (but in the same column as the old initials) should be copied to table Y. That's what my 2nd action should do.
What am I doing wrong?
Thank you.
Have a look at the CREATE TRIGGER syntax. It is not possible to specify AFTER and BEFORE option in one trigger.
So, you should create two separate triggers.
If you want to optimize code and combine trigger's bodies, then you can write a stored proceure and call it from the triggers.
Related
I want to automatically copy data from one column to another in one table.
The following query does this, but not automatically:
UPDATE table SET columnB = columnA
Could someone show a trigger for this (that does it automatically)?
Note: columnB and columnA are integers.
Should be as simple as:
delimiter //
CREATE TRIGGER before_table_update BEFORE UPDATE ON table
FOR EACH ROW
BEGIN
SET new.columnB = new.columnA;
END //
delimiter ;
Be aware, this will only effect UPDATE's. You will need to copy this trigger for inserts as well before_table_insert BEFORE INSERT...
Having a table with the name transitions, I want to change the values of all the rows after any update is made.
I'm using the following trigger, which changes only the ROW that I'm making the update to.
CREATE TRIGGER signaturetrigger BEFORE UPDATE ON `transactions` FOR EACH ROW
BEGIN
SET New.signature = '288';
END
I'm trying to change all the rows to signature = 288, how can I modify the trigger in order to archieve that? I thought that using FOR EACH ROW would be enough.
Thanks in advance.
You can use an after update trigger with an update statement:
CREATE TRIGGER signaturetrigger AFTER UPDATE ON `transactions`
FOR EACH ROW
BEGIN
UPDATE transactions
SET New.signature = '288';
END;
This does seem like a very strange thing to do, however.
Consider an alternative: just add an UpdatedAt column into the table and update the signature in that row. Then, when you want the most recent signature use:
select signature
from transactions
order by UpdatedAt desc
limit 1;
An index on transactions(UpdatedAt, signature) will make this quite speedy. And, the update will go much, much faster than updating all rows.
I was trying to create trigger which can update value of column user_count of table user_details using value of u_count of table user_info.
CREATE TRIGGER `test`
AFTER INSERT ON `user_details` FOR EACH ROW
BEGIN
DECLARE default_user_count int(11);
SELECT u_count INTO #default_user_count FROM
user_info WHERE user_info.id= user_details.id_c;
IF user_details.user_count= 0
THEN UPDATE user_details SET
user_count = default_user_count
WHERE user_details.id_c = user_info.id;
END IF;
END
Trigger saved successfully but when i tried to insert value in both table it is preventing to insert record into user_details means no row inserted in 2 this table, if we delete trigger then its working.
Can anyone let me know wrong with this trigger?
THanks,
M.
It's not really clear what you're trying to accomplish, but it seems like it's something like what we have below.
There are numerous errors in and ambiguities in your trigger.
Confusion on variables -- DECLARE default_user_count INT(11); does not declare the user-defined variable #default_user_count. It declares the program variable default_user_count. The # prefix references an entirely different variable scope and namespace.
SELECT and UPDATE from the table which invoked the trigger doesn't usually make sense (SELECT) or is completely invalid (UPDATE).
With in a trigger, you are operating FOR EACH ROW -- that is, for each row included in the statement that invoked the trigger. Inside an INSERT trigger, the NEW values for the row are in a pseudo-table/pseudo-row accessible via the alias NEW. For UPDATE triggers, there are NEW and OLD row values, and for DELETE triggers, just OLD.
AFTER INSERT doesn't seem to make sense. I think you're looking for BEFORE INSERT -- that is, while processing an INSERT INTO ... query, before the newly-inserted row actually gets written into the table, modify its values accordingly. The resulting row contains the original values except where the trigger has modified them.
SELECT ... INTO a variable is a practice you should not get into the habit of, because it can bite you in a way a scalar subquery can't, by leaving a variable unexpectedly unaltered instead of setting it to NULL as would be expected. In this case, it would have made no difference, but it's still a caution worth mentioning... and in this case, I've eliminated that intermediate variable altogether, so the subquery is the only option.
If you are trying to set a value in this table using a value found in another table, all you need to do is SET NEW.column_name equal to the value you want used in the row instead of the value provided with the insert statement.
CREATE TRIGGER `test`
BEFORE INSERT ON `user_details` FOR EACH ROW
BEGIN
IF NEW.user_count = 0 /* maybe also >> */ OR NEW.user_count IS NULL /* << this */ THEN
SET NEW.user_count = (SELECT ui.u_count
FROM user_info ui
WHERE ui.id = NEW.id_c);
END IF;
END
Again, it's unclear how the two tables are connected based on the content of the original question, but this appears to do what you're trying to accomplish.
I'm fairly new to triggers and have already tried searching for a solution to my question with little results. I want to update a single row's start time column whenever it's active column is set to 1.
I have two columns ACTIVE (number) and START_TIME (timestamp) in my_table. I would like to create a PL/SQL trigger that updates the START_TIME column to current_timestamp whenever an update statement has been applied to the ACTIVE column - setting it to 1.
So far I have only seen examples for inserting new rows or updating entire tables which isn't what I'm looking to do. I'd have thought there would be a fairly simple solution to my problem.
This is what I've got so far from other examples. I know the structure of my solution is poor and I'm asking for any input to modify my trigger to achieve my desired result.
CREATE OR REPLACE TRIGGER routine_active
AFTER UPDATE ON my_table
FOR EACH ROW
WHEN (my_table.ACTIVE = 1)
begin
insert my_table.start_time = current_timestamp;
end;
\
you can use like this .it may help you
write the update query instead of insert query
CREATE OR REPLACE TRIGGER routine_active
AFTER UPDATE ON my_table
FOR EACH ROW
WHEN (new.ACTIVE = 1)
begin
update my_table set start_time =current_timestamp;
end;
I think it should be a BEFORE UPDATE, not AFTER UPDATE, so it saves both changes with a single action. Then you don't need the INSERT or UPDATE statements. I also added the "OF active" clause, so it will only start this trigger if that column was updated, which may reduce the workload if other columns get updated.
CREATE OR REPLACE TRIGGER routine_active
BEFORE UPDATE OF active ON my_table
FOR EACH ROW
BEGIN
IF active = 1
THEN
:NEW.start_time = current_timestamp;
END IF;
END;
I am currently in the process of writing my first trigger in MySQL within PHPmyadmin. I would like it so that when an item in one table is updated, a row in another table is inserted. Several columns of the row that is to be inserted in the second table are determined by the values being updated in the first table.
Therefore, I need to INSERT a new row in table B when an update occurs on table A. And some of the values of the columns in table B are to be defined by the values in the updated table A row which caused the trigger to run.
Please find the trigger below.
CREATE TRIGGER `before_categoryiteminstance_update` BEFORE UPDATE ON `TABLEA`
FOR EACH ROW BEGIN
declare f_guidcategoryiteminstance int;
declare f_guidcategory int;
INSERT INTO TABLEB
SET
f_guidcategoryiteminstance =(SELECT guidcategoryiteminstance FROM inserted),
f_guidcategory =(SELECT guidcategory FROM inserted),
guiduser= f_guidcategory,
guidcategoryinstance= f_guidcategoryiteminstance,
number= number +1,
dateofaction= NOW(); END
The trigger can be added to the DB fine. However, when I attempt to update a row on table A (which should cause the trigger to run), I get an error stating that the table Inserted does not exist. However, I was under the impression that Inserted should be a logical table that contains the results of the initial part of the trigger. Is this only the case if the trigger is being run on an insert and not an update? If so, is there an equivalent for an update trigger?