How to set auto increment value to another field using trigger - mysql

I need a solution for copy the auto increment value to userid column when insert the record.
I have two column like id(AI),userid. Here I have used a trigger
CREATE TRIGGER adduserid BEFORE INSERT ON user
FOR EACH ROW SET NEW.userid = NEW.id
The problems is triggers invoke before insert,so it will get id as 0.
Suggest me how can I modify the trigger?

Sample:
Table definition:
CREATE TABLE departments (
ID NUMBER(10) NOT NULL,
DESCRIPTION VARCHAR2(50) NOT NULL);
ALTER TABLE departments ADD (
CONSTRAINT dept_pk PRIMARY KEY (ID));
CREATE SEQUENCE dept_seq;
Trigger definition:
CREATE OR REPLACE TRIGGER dept_bir
BEFORE INSERT ON departments
FOR EACH ROW
BEGIN
SELECT dept_seq.NEXTVAL
INTO :new.id
FROM dual;
END;
Syntax Link1:https://dev.mysql.com/doc/refman/5.0/en/create-trigger.html

Related

MYSQL: I am trying to set a trigger to update my current row on update.(not updating all the rows just the updated row) [duplicate]

Here's what I'm trying to do:
When there's a new INSERT into the table ACCOUNTS, I need to update the row in ACCOUNTS where pk = NEW.edit_on by setting status='E' to denote that the particular (old) account has been edited.
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` AFTER INSERT on ACCOUNTS
FOR EACH ROW BEGIN
update ACCOUNTS set status='E' where ACCOUNTS.pk = NEW.edit_on ;
END$$
DELIMITER ;
The requirement is NOT that I manipulate the newly inserted column, but an already existing column with pk = NEW.edit_on
However, I can't update the same table: Can't update table ACCOUNTS ... already used by the statement that invoked this trigger
Please suggest a workaround
PS: I have already gone through Updating table in trigger after update on the same table, Insert into same table trigger mysql, Update with after insert trigger on same table and mysql trigger with insert and update after insert on table but they dont seem to answer my question.
Edit
ACCOUNTS Table:
CREATE TABLE `ACCOUNTS` (
`pk` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(9) unsigned NOT NULL,
`edit_on` bigint(10) unsigned DEFAULT NULL,
`status` varchar(1) NOT NULL DEFAULT 'A',
PRIMARY KEY (`pk`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2147483726 DEFAULT CHARSET=latin1
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.
This is how I update a row in the same table on insert
activationCode and email are rows in the table USER.
On insert I don't specify a value for activationCode, it will be created on the fly by MySQL.
Change username with your MySQL username and db_name with your db name.
CREATE DEFINER=`username`#`localhost`
TRIGGER `db_name`.`user_BEFORE_INSERT`
BEFORE INSERT ON `user`
FOR EACH ROW
BEGIN
SET new.activationCode = MD5(new.email);
END
Had the same problem but had to update a column with the id that was about to enter, so you can make an update should be done BEFORE and AFTER not BEFORE had no id so I did this trick
DELIMITER $$
DROP TRIGGER IF EXISTS `codigo_video`$$
CREATE TRIGGER `codigo_video` BEFORE INSERT ON `videos`
FOR EACH ROW BEGIN
DECLARE ultimo_id, proximo_id INT(11);
SELECT id INTO ultimo_id FROM videos ORDER BY id DESC LIMIT 1;
SET proximo_id = ultimo_id+1;
SET NEW.cassette = CONCAT(NEW.cassette, LPAD(proximo_id, 5, '0'));
END$$
DELIMITER ;
On the last entry; this is another trick:
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_schema = ... and table_name = ...
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` **BEFORE** INSERT on ACCOUNTS
FOR EACH ROW BEGIN
SET NEW.STATUS = 'E';
END$$
DELIMITER ;
Instead you can use before insert and get max pkid for the particular table and then update the maximium pkid table record.

MYSQL - Trigger -update /deletion

I have to create a trigger a which captures old and new value while updation & deletion taken place
Audit table :
create table if not EXISTS tbl_audits
(
TA_Auditid int AUTO_INCREMENT PRIMARY key,
TA_Name varchar(100),
TA_Oldvalue varchar(1000),
TA_Newvalue varchar(1000),
TA_Actiontaken varchar(100),
TA_createddt datetime,
TA_createdby varchar(100)
)
DELIMITER //
create TRIGGER TRfiledetails_update
BEFORE update on tbl_file_details
for EACH ROW
BEGIN
insert into tbl_audits
set TA_createddt =CURRENT_TIMESTAMP,
TA_Actiontaken ='update',
TA_Name ='File',
TA_Oldvalue =old.FL_dtstartdt ,
TA_Newvalue =new.FL_dtstartdt
end //
DELIMITER ;
In my main table i have to create trigger an event on two columns startdt and enddate.
In this case I would like to know whether I need to create two triggers separately for each column.
Is it possible to create two columns action on same trigger or need to create separate columns in audit table.

How can I update MySQL table row's when 'BEFORE UPDATE' trigger is firing?

I created a table
Databases Name - mytrigger;
Table name - employee_audit
use mytrigger;
create table employee_audit(
id int auto_increment primary key,
employeeNumber int not null,
lastName varchar(50) not null,
changee datetime default null,
action varchar(50) default null
);
After that, I created one update trigger
My trigger name is
before_employees_update
DELIMITER $$
create trigger before_employees_update
before update on employee_audit
for each row
begin
insert into employee_audit
set action ='update',
employeeNumber = OLD.employeeNumber,
lastName = OLD.lastName,
changee = now();
end$$
DELIMITER ;
After that, I inserted values in table using this command ->
insert into employee_audit values(1,112,'prakash','2015-11-12 15:36:20' ,' ');
After that, I want to update my table row where id =1
update employee_audit set lastName = 'Sharma' where employeeNumber =112;
But it is not executed give an error
ERROR 1442 (HY000): Can't update table 'employee_audit' in stored
function/trigger because it is already used by statement which invoked
this stored function/trigger.
When I searched on Google I found a lot of Question with the same error. But not able to fix my problem. what is the reason I'm not able to update my row?
What i suggest,you can create one log table like employee_audit_LOG .
And on every insert or update in main table you can make new entry in this table or update existing record.
Also you can add updated_timestamp column to that LOG table which maintain when did specific record get updated.
The error itself tells you the answer. This is because, you can't use the same table on which trigger is being executed. You need to store your audit logs into some different table.

Obtain value of Primary Key for Trigger Updated Row (MySQL)

I wish to identify the value for the PRIMARY KEY of the row that I have just updated.
i.e : X is an int value PRIMARY KEY on the person table.
This trigger works when I manually enter the int value e.g replace X with 1001.
use mydatabase;
DROP TRIGGER update_approved;
delimiter $
CREATE TRIGGER update_approved AFTER UPDATE ON person
FOR EACH ROW BEGIN
UPDATE referral_person SET
approved = 1 WHERE
id = X;
END$
delimiter ;
just change it to
....
id = OLD.ColumnName
where ColumnName is the name of your primary key column.

MySQL - Trigger for updating same table after insert

Here's what I'm trying to do:
When there's a new INSERT into the table ACCOUNTS, I need to update the row in ACCOUNTS where pk = NEW.edit_on by setting status='E' to denote that the particular (old) account has been edited.
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` AFTER INSERT on ACCOUNTS
FOR EACH ROW BEGIN
update ACCOUNTS set status='E' where ACCOUNTS.pk = NEW.edit_on ;
END$$
DELIMITER ;
The requirement is NOT that I manipulate the newly inserted column, but an already existing column with pk = NEW.edit_on
However, I can't update the same table: Can't update table ACCOUNTS ... already used by the statement that invoked this trigger
Please suggest a workaround
PS: I have already gone through Updating table in trigger after update on the same table, Insert into same table trigger mysql, Update with after insert trigger on same table and mysql trigger with insert and update after insert on table but they dont seem to answer my question.
Edit
ACCOUNTS Table:
CREATE TABLE `ACCOUNTS` (
`pk` bigint(10) unsigned NOT NULL AUTO_INCREMENT,
`user_id` bigint(9) unsigned NOT NULL,
`edit_on` bigint(10) unsigned DEFAULT NULL,
`status` varchar(1) NOT NULL DEFAULT 'A',
PRIMARY KEY (`pk`) USING BTREE) ENGINE=InnoDB AUTO_INCREMENT=2147483726 DEFAULT CHARSET=latin1
It seems that you can't do all this in a trigger. According to the documentation:
Within a stored function or trigger, it is not permitted to modify a table that is already being used (for reading or writing) by the statement that invoked the function or trigger.
According to this answer, it seems that you should:
create a stored procedure, that inserts into/Updates the target table, then updates the other row(s), all in a transaction.
With a stored proc you'll manually commit the changes (insert and update). I haven't done this in MySQL, but this post looks like a good example.
This is how I update a row in the same table on insert
activationCode and email are rows in the table USER.
On insert I don't specify a value for activationCode, it will be created on the fly by MySQL.
Change username with your MySQL username and db_name with your db name.
CREATE DEFINER=`username`#`localhost`
TRIGGER `db_name`.`user_BEFORE_INSERT`
BEFORE INSERT ON `user`
FOR EACH ROW
BEGIN
SET new.activationCode = MD5(new.email);
END
Had the same problem but had to update a column with the id that was about to enter, so you can make an update should be done BEFORE and AFTER not BEFORE had no id so I did this trick
DELIMITER $$
DROP TRIGGER IF EXISTS `codigo_video`$$
CREATE TRIGGER `codigo_video` BEFORE INSERT ON `videos`
FOR EACH ROW BEGIN
DECLARE ultimo_id, proximo_id INT(11);
SELECT id INTO ultimo_id FROM videos ORDER BY id DESC LIMIT 1;
SET proximo_id = ultimo_id+1;
SET NEW.cassette = CONCAT(NEW.cassette, LPAD(proximo_id, 5, '0'));
END$$
DELIMITER ;
On the last entry; this is another trick:
SELECT AUTO_INCREMENT FROM information_schema.tables WHERE table_schema = ... and table_name = ...
DELIMITER $$
DROP TRIGGER IF EXISTS `setEditStatus`$$
CREATE TRIGGER `setEditStatus` **BEFORE** INSERT on ACCOUNTS
FOR EACH ROW BEGIN
SET NEW.STATUS = 'E';
END$$
DELIMITER ;
Instead you can use before insert and get max pkid for the particular table and then update the maximium pkid table record.