Database-Trigger to Delete row where condition True: - mysql

I need trigger That Deletes row where in table paym both columns table1 and table2 are not empty.
Example in tables below:
table: paym
ID username table1 Table2
+-------+-------------+-------------+-----------+
| 1 | John | Value | Value |
+-------+-------------+-------------+-----------+
| 2 | Alex | Null | Null |
+-------+-------------+-------------+-----------+
Condition is True: After Deleted row:
ID username table1 Table2
+-------+-------------+-------------+-----------+
| 2 | Alex | Null | Null |
+-------+-------------+-------------+-----------+
My attemp is: (Not working)
CREATE trigger DeleteROW
AFTER UPDATE ON paym
FOR EACH ROW
BEGIN
IF (NEW.table1 IS NOT NULL AND NEW.table2 IS NOT NULL) THEN
DELETE
FROM
paym WHERE table1 and table2 IS NOT NULL ;
END IF;
END

A trigger cannot modify the table it is running on.
You should create a stored procedure to handle this, and call that instead of the DELETE command...

Related

mysql trigger after update column from another table

I have 2 tables which are below.
I would like to create a trigger for table_one. when changed the username in table_one, update user_id value from the table_two user value.
table_one:
+--------------+----------+
| user_id | username |
+--------------+----------+
| 15 | robin |
| 46 | albert |
+--------------+----------+
table_two:
+--------------+----------+
| id | user |
+--------------+----------+
| 1 | john |
| 2 | jack |
| 3 | robin |
| 4 | kylie |
| 5 | robert |
| 6 | albert |
| 7 | jay |
+--------------+----------+
thanks in advance
Do a BEFORE UPDATE trigger, not an AFTER UPDATE trigger.
(I don't think it's possible in an AFTER UPDATE trigger to modify the row that was updated, that fired the trigger. I could be wrong about that, but I just can't wrap my brain around how that would work.)
This is a demonstration of a BEFORE UPDATE trigger on table_one that assigns a value to the user_id column (of the row being updated) based on the result from a query:
DELIMITER $$
CREATE TRIGGER ...
BEFORE UPDATE ON table_one
BEGIN
# local variable we will temporarily store a value fetched from a query
DECLARE li_new_id BIGINT DEFAULT NULL; # match datatype of table_two.id
# lookup `id` value from `table_two` with a SQL query
SELECT s.id
INTO li_new_id
FROM table_two s
WHERE s.user = NEW.username
ORDER BY s.id
LIMIT 1 ;
# assign the value we fetched to the `user_id` column of the row being updated
SET NEW.user_id := li_new_id ;
END$$
DELIMITER ;
Note that if the query doesn't find a matching row, the local variable will have a NULL value. So the SET statement will assign NULL to to the user_id column. There's no check in the trigger that the value we assign won't violate a constraint (NOT NULL, UNIQUE, FOREIGN KEY).

Stored-Procedure to Delete row where this condition True:

I need Stored-Procedure That AUTOMATICALLY Deletes everytime row, where in table paym both columns table1 and table2 are not empty.
Example in tables below:
table: paym
ID username table1 Table2
+-------+-------------+-------------+-----------+
| 1 | John | Value | Value |
+-------+-------------+-------------+-----------+
| 2 | Alex | Null | Null |
+-------+-------------+-------------+-----------+
Condition is True: After Deleted row:
ID username table1 Table2
+-------+-------------+-------------+-----------+
| 2 | Alex | Null | Null |
+-------+-------------+-------------+-----------+
My attemp is: (Not working)
CREATE PROCEDURE DeleteRow
BEGIN
DELETE
FROM
paym WHERE table1 and table2 IS NOT NULL ;
END;
CREATE PROCEDURE DeleteRow
BEGIN
DELETE
FROM
paym WHERE table1 IS NOT NULL AND table2 IS NOT NULL ;
END;
Your logic is right here, but the syntax is wrong.
After every field on WHERE clause you must specify a condition, just like this:
CREATE PROCEDURE DeleteRow
BEGIN
DELETE
FROM
paym WHERE table1 IS NOT NULL AND table2 IS NOT NULL ;
END;
You can also use COALESCE
CREATE PROCEDURE DeleteRow
BEGIN
DELETE FROM paym WHERE COALESCE(table1,table2) IS NOT NULL;
END;
the code should read table is not null and table 2 is not null, as you need to have a condition after an and statement.

SQL Statement to auto-increment values in column if row exists without primary key

I have a table with this data
mysql> SELECT * FROM prueba;
+----+------+------+------+
| id | U1 | U2 | cant |
+----+------+------+------+
| 2 | U123 | U124 | 2 |
+----+------+------+------+
I neeed to increment 'cant' in 1 everytime i execute the statement.
But if the row doesn't exists it has to be created.
The columns U1 and U2 are pairs of data, this means a U1,U2 pair is unique, and thats the condition to search if the record exists.
This is what i have made so far.
select U1,U2,cant,
(
case when exists (select U1,U2 from prueba where U1='U123'
and U2='U124')
then 1
else 0
end
) as tmp
from prueba
See the accepted answer in insert-to-table-or-update-if-exists-mysql. The idea is to use MySQLs
INSERT INTO ... ON DUPLICATE KEY UPDATE ...

Creating a trigger on insert on a table, that creates new rows on another table, according to amount of row on another (3rd) table

Assume the following structure:
Table1:
ID | name
Table2:
ID | name
Table3:
ID | table1_id | table2_id | value
I want to build a trigger, after insert to Table1 if id not exist, to create new rows for each row in Table2 inside Table3 with the corresponding IDs.
What I did so far is creating this logic in php, I have never created triggers this complex before so I don't really know how to approach this.
Example:
Customers Table after insert:
+----+------+
| ID | Name |
+----+------+
| 1 | Dan |
+----+------+
Currency Table:
+----+------+
| ID | Name |
+----+------+
| 1 | USD |
| 2 | EUR |
+----+------+
Customers Currency Table after trigger
+----+---------------+-------------+-------+
| ID | customer_id | currency_id | Value |
+----+---------------+-------------+-------+
| 1 | 1 | 1 | NULL |
| 2 | 1 | 2 | NULL |
+----+---------------+-------------+-------+
Another option that you can use is:
DELIMITER $$
DROP TRIGGER /*!50032 IF EXISTS */ `trg_bi`$$
CREATE TRIGGER `trg_bi` BEFORE INSERT ON `table1`
FOR EACH ROW
BEGIN
INSERT INTO `table3` (`table1_id`, `table2_id`)
SELECT NEW.`id`, `t2`.`id`
FROM `table2` `t2`
WHERE NOT EXISTS (SELECT NULL FROM `table1` `t1` WHERE `t1`.`id` = NEW.`id`);
END$$
DELIMITER ;
Here is validated by the id column table1, but you can use the column you want to validate, however, depends as validate that there is no 'customer' in table1.
SQL Fiddle example
To deal with this you need to use cursor in trigger, here is a nice tutorial on this http://www.mysqltutorial.org/mysql-cursor/
Now in your case I would suggest that the customer table id should be primary key auto incremented so that you always have unique value
So here how it should be
create table customer (id int primary key auto_increment , name varchar (100));
create table currency (id int primary key auto_increment, name varchar(100));
insert into currency (name) values ('USD'),('EUR') ;
create table customer_currency (id int primary key auto_increment, customer_id int , currency_id int , val varchar(100));
The trigger will be something as
delimiter //
create trigger customer_add after insert on customer
for each row
begin
DECLARE done INT DEFAULT FALSE;
DECLARE currency_id int;
DECLARE currency_val varchar(100);
DECLARE cur CURSOR FOR SELECT id,name FROM currency;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE;
OPEN cur;
ins_loop: LOOP
FETCH cur INTO currency_id,currency_val;
IF done THEN
LEAVE ins_loop;
END IF;
INSERT INTO customer_currency (customer_id,currency_id,val) VALUES (NEW.id,currency_id,currency_val);
END LOOP;
CLOSE cur;
end ; //
delimiter ;
Now in mysql lets add a record on customer table
mysql> insert into customer (name) values ('Abhik') ;
Query OK, 1 row affected (0.02 sec)
Now lets see what is there in the customer_currency symbol
mysql> select * from customer_currency ;
+----+-------------+-------------+------+
| id | customer_id | currency_id | val |
+----+-------------+-------------+------+
| 1 | 1 | 1 | USD |
| 2 | 1 | 2 | EUR |
+----+-------------+-------------+------+
In the trigger I am adding the currency value as well in the 3rd table if you do not want then can ignore that and it will become null.
You can write an after delete trigger on customer and delete the data from customer_currency where customer_id is the id of the deleted row in customer table.

Copy to another table on mysql update

I have a mysql table that whenever there is an add, modify/update, or delete, I want to take the row and add it to an "archive" table (before it is updated or deleted). This is for a historical archive (i.e. what happened). Is there a way to do this in the database layer "automatically"? Is there a better way...
You'll need a group of triggers that cover all operations (insert, update, delete).
Let's say you have a table
CREATE TABLE table1
(
table1_id int not null auto_increment primary key,
column1 varchar(32)
);
and you created the following history table for it
CREATE TABLE table1_history
(
history_id int not null auto_increment primary key,
dt datetime not null,
operation varchar(6) not null,
table1_id int not null,
column1 varchar(32) not null
);
Now your triggers might look something like
CREATE TRIGGER tg_ai_table1
AFTER INSERT ON table1
FOR EACH ROW
INSERT INTO table1_history (dt, operation, table1_id, column1)
VALUES(NOW(), 'insert', NEW.table1_id, NEW.column1);
CREATE TRIGGER tg_au_table1
AFTER UPDATE ON table1
FOR EACH ROW
INSERT INTO table1_history (dt, operation, table1_id, column1)
VALUES(NOW(), 'update', NEW.table1_id, NEW.column1);
CREATE TRIGGER tg_bd_table1
BEFORE DELETE ON table1
FOR EACH ROW
INSERT INTO table1_history (dt, operation, table1_id, column1)
VALUES(NOW(), 'delete', OLD.table1_id, OLD.column1);
If we issue the following DML statements against table1
INSERT INTO table1 (column1) VALUES ('value1'), ('value2');
UPDATE table1 SET column1 = 'value11' WHERE table1_id = 1;
DELETE FROM table1 WHERE table1_id = 2;
table1 will contain
| TABLE1_ID | COLUMN1 |
|-----------|---------|
| 1 | value11 |
table1_history will contain
| HISTORY_ID | DT | OPERATION | TABLE1_ID | COLUMN1 |
|------------|--------------------------------|-----------|-----------|---------|
| 1 | January, 04 2014 06:31:15+0000 | insert | 1 | value1 |
| 2 | January, 04 2014 06:31:15+0000 | insert | 2 | value2 |
| 3 | January, 04 2014 06:31:15+0000 | update | 1 | value11 |
| 4 | January, 04 2014 06:31:15+0000 | delete | 2 | value2 |
Here is SQLFiddle demo
Try to use Trigger
eg:
DROP TRIGGER auditlog
CREATE TRIGGER auditlog BEFORE UPDATE ON frequencies
FOR EACH ROW BEGIN
INSERT INTO frequencies_audit select * from frequencies where freqId = NEW.freqId;
END;