I have 2 tables member_details and archives. I want a trigger that will insert deleted data from member_details into archives as soon as as a particular record is deleted from the member_details table.
DELIMITER $$
CREATE TRIGGER member_details_ADEL AFTER DELETE ON member_details
FOR EACH ROW
insert into archives values
This is how you can do it, lets say you have a table called test with the following data
mysql> select * from test ;
+----------------------+
| id |
+----------------------+
| 10 |
| 20 |
| 30 |
+----------------------+
You have another table called test1 as no data currently
mysql> select * from test1 ;
Empty set (0.00 sec)
Now lets write a trigger so that when there is a delete on the test table the deleted record gets added to the test1 table. You need to use after delete trigger for this and the using old.col you can get the data
In this example I have only one column you can use old.col name to access any column on the table where the trigger is executing
delimiter //
create trigger log_delete after delete on test
for each row
begin
insert into test1 (id) values (old.id);
end ; //
delimiter ;
Now lets delete a record in test table as
mysql> delete from test where id = 10 ;
Query OK, 1 row affected, (0.00 sec)
mysql> select * from test ;
+----------------------+
| id |
+----------------------+
| 20 |
| 30 |
+----------------------+
2 rows in set (0.00 sec)
mysql> select * from test1 ;
+----------------------+
| id |
+----------------------+
| 10 |
+----------------------+
1 row in set (0.00 sec)
Now as you can see the deleted row has been added to the table test1.
All you need to do is to set proper table names and the column names in the above trigger along with the trigger name you want to have
USE church;
DELIMITER $$
CREATE TRIGGER member_details_ADEL AFTER DELETE ON member_details
FOR EACH ROW
begin
insert into archives
(TITLE, NAME, `NAME OF SPOUSE`, `LEVEL OF EDUCATION`, ADDRESS, `PHONE NUMBER`, OCCUPATION, `DATE JOINED`, `EMERGENCY CONTACT`)
values
(old.TITLE, old.NAME, old.`NAME OF SPOUSE`, old.`LEVEL OF EDUCATION`, old.`ADDRESS`, old.`PHONE NUMBER`,old.`OCCUPATION`, old.`DATE JOINED`, old.`EMERGENCY CONTACT`);
END ; $$
delimiter ;
Make sure to backtick the column names when there is a space in between or in case using a reserve keyword.
You can use OLD keyword to fetch values from the deleted record.
But you have to specify column names with the insert statement.
Example :
delimiter //
drop trigger if exists member_details_adel //
create trigger member_details_adel
after delete on member_details
for each row
insert
into archives( col1, col2, colx )
values( old.col1, old.col2, old.colx );
//
delimiter ;
Change and extend column names as per your table needs.
Update 1:
There was syntax error in your tried trigger body.
Corrected one is as follows:
delimiter $$
create trigger member_details_adel
after delete on member_details
for each row
insert
into archives (title, name, name of spouse,
level of education, address,
phone number, occupation,
date joined, emergency contact)
values (old.title, old.name, old.`name of spouse`,
old.`level of education`, old.`address`,
old.`phone number`, old.`occupation`,
old.`date joined`, old.`emergency contact`);
$$
delimiter ;
Related
Let's say I have two BEFORE UPDATE triggers on the same table. We'll call them trigger A and trigger B. Order is enforced, so A will always be executed first, and B will always be executed second.
Will OLD and NEW reference the same values in the body of both A and B?
Or will the NEW values of A become the OLD values of B? Meaning B is referencing a new UPDATE statement, which is a product of A?
The OLD values reference the row before the UPDATE. That is, before any of the triggers execute. These never change during the triggers.
The NEW values reference the row with values you mean to change.
One trigger may modifies the NEW values. Then the subsequent trigger will see the modified values, still in the NEW row.
Demo:
mysql> create table mytable (id serial primary key, x int);
mysql> insert into mytable set x = 1;
mysql> delimiter $$
mysql> create trigger t1 before update on mytable
for each row begin set NEW.x = NEW.x + 1; end$$
mysql> create trigger t2 before update on mytable
for each row follows t1 begin set #x_old = OLD.x; set #x_new = NEW.x; end$$
mysql> delimiter ;
mysql> update mytable set x = 10;
mysql> select #x_old, #x_new;
+--------+--------+
| #x_old | #x_new |
+--------+--------+
| 1 | 11 |
+--------+--------+
I need a trigger in phpmyadmin for 2 tables.
I have two tables called users and group_has_users. Table group_has_users has 2 values called group_id and user_id.
I'm trying to make a trigger that automatically inserts new data to group_has_users table with user_id when new user is created in users table( with group_id set to 1)
How to do this with phpmyadmin trigger?
insert into group_has_users (user_id) values (new.user_id);
I have no clue to make it group_id to set 1.
I think this is what you want:
delimiter $$
create trigger after_insert_users
after insert on users
for each row begin
if new.group_id = 1 then
insert into group_new_users (user_id) values (new.user_id);
end if;
end $$
delimiter ;
Note that you will have to run this in your cli or in mysql workbench
Everytime a new record is created in table users, you are looking to automatically create a new record in group_has_users, with a default group_id of 1.
Consider the following trigger:
DELIMITER //
CREATE TRIGGER users_after_insert
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO group_has_users(group_id, user_id) VALUES(1, NEW.user_id);
END;
//
Demo on DB Fiddle:
DELIMITER //
CREATE TABLE users (user_id int)//
CREATE TABLE group_has_users (group_id int, user_id int)//
CREATE TRIGGER users_after_insert
AFTER INSERT ON users FOR EACH ROW
BEGIN
INSERT INTO group_has_users(group_id, user_id) VALUES(1, NEW.user_id);
END;
//
INSERT INTO users(user_id) values(1);
SELECT * FROM group_has_users;
| group_id | user_id |
| -------- | ------- |
| 1 | 1 |
Hello Im trying to find a way the UPDATE or INSERT data with one query.
I have a table with like this:
+------+-------------+
| User | action_type |
+------+-------------+
| Jon | 1 |
| Kate | 2 |
| Jon | 4 |
+------+-------------+
I want to insert new value for Jon only if there is no values of Jon.
If I have values of Jon I want to update all the rows with Jon.
Ive read about INSERT ... ON DUPLICATE KEY UPDATE but I dont have unique values.
Thanks for helping.
you can count the entries for jon. If exists update else insert.
if you want to implement only using sql you can use an stored procedure
something like this:
CREATE PROCEDURE insertorupdate (IN name VARCHAR(20))
BEGIN
DECLARE numJon INT;
SELECT COUNT(*) INTO numJon FROM table WHERE User=name;
IF numJon > 0 THEN
// UPDATE ;
ELSE
// INSERT
END IF;
END
Then you can call you Store Procedure:
CALL insertorupdate('John');
If you can do it from your app you can call the same thing but separatelly. Do a select count, test if count if grater than 0 and then do the insert or the update on DB
Don't count like in user468891's answer. It might become a performance issue. Instead just check if an entry exists. As soon as an entry is found, the query returns true, count continues to find all records.
DELIMITER $$
CREATE PROCEDURE insertorupdate (IN name VARCHAR(20))
BEGIN
IF (EXISTS(SELECT 1 FROM table WHERE User = name)) THEN
// UPDATE...
ELSE
// INSERT...
END IF;
END $$
DELIMITER ;
Are MySQL AFTER INSERT triggers always being executed directly after the INSERT statement, or is it possible that 2 inserts occur and after that 2 triggers occur?
I'm writing this trigger namely:
CREATE DEFINER=`p28004_bf4`#`localhost` TRIGGER `setId`
AFTER INSERT ON `playerkills`
FOR EACH ROW
BEGIN
INSERT INTO globals () VALUES();
UPDATE playerkills SET globalId = LAST_INSERT_ID() WHERE id = ROW.id;
END
And I'm worried about what will happen if the insert statements somehow get interleaved, the globalId must always be consistent, like a global unique identifier accross multiple tables.
Globals table:
id (Primary Key, Int, Auto Increment)
Playerkills table:
id (Primary Key, int, Auto increment)
globalId (Key, Int)
etc.
Ultimately it doesn't matter what order concurrent commands run in this case. The LAST_INSERT_ID function is smart enough not to give you the ID inserted by a someone else's concurrent query.
As a relatively simple example, I opened two mysql sessions and created a table called globals with an autoincrement primary key, then alternated back and forth typing these commands.
## Session 1 ## ## Session 2 ##
mysql> INSERT INTO globals () VALUES ();
Query OK, 1 row affected (0.00 sec)
mysql> INSERT INTO globals () VALUES ();
Query OK, 1 row affected (0.00 sec)
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 1 |
+------------------+
1 row in set (0.00 sec)
mysql> SELECT LAST_INSERT_ID();
+------------------+
| LAST_INSERT_ID() |
+------------------+
| 2 |
+------------------+
1 row in set (0.00 sec)
This question already has answers here:
Concatenating a string and primary key Id while inserting
(2 answers)
Closed 6 years ago.
I have a table with 2 columns. The ID column auto increments. I'm trying to auto increment the user column with the same ID as the id column, but with a "user" prefix (example: user100, where the ID is also 100) basically just like what is done on stackoverflow.
CREATE TABLE test_table (
id MEDIUMINT NOT NULL AUTO_INCREMENT,
user CHAR(30) NOT NULL,
PRIMARY KEY (id)
) ENGINE=MyISAM;
Is there a way of doing this in 1 query? Instead of inserting into the DB, then querying to get the ID, and inserting the ID into the user column?
Use a BEFORE trigger:
DELIMITER $$
CREATE TRIGGER test_table_trigger
BEFORE INSERT ON test_table
FOR EACH ROW BEGIN
SET NEW.`user` = CONCAT(NEW.`user`, NEW.id);
END $$
DELIMITER ;
Documentation: MySQL triggers
You can do a trigger
Before Trigger:
mysql> truncate table test_table;
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter $$
mysql> CREATE TRIGGER test_table_trigger
-> BEFORE insert ON test_table
-> FOR EACH ROW
-> BEGIN
-> SET new.user = CONCAT('user', (SELECT AUTO_INCREMENT FROM information_schema.TABLES WHERE TABLE_SCHEMA=DATABASE() AND TABLE_NAME='test_table'));
-> END $$
Query OK, 0 rows affected (0.00 sec)
mysql> delimiter ;
mysql> INSERT INTO test_table values ();
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> INSERT INTO test_table values ();
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> INSERT INTO test_table values ();
Query OK, 1 row affected, 1 warning (0.00 sec)
mysql> select * FROM test_table;
+----+-------+
| id | user |
+----+-------+
| 1 | user1 |
| 2 | user2 |
| 3 | user3 |
+----+-------+
3 rows in set (0.00 sec)
The above should then use the auto-increment after it's designated to the id column and append it to the string user. The auto increment ID is pulled from Information_Schema, as if this is in a transaction or many queries, it could be set wrong.
Maybe you can try this, picking up last inserted id and concatenating string with converted value:
INSERT INTO test_table (user) VALUES ('user')
UPDATE test_table
SET user = user + CAST(LAST_INSERT_ID() AS VARCHAR)
WHERE id = LAST_INSERT_ID()