I'm trying to create a trigger that will allow only one record in a database, so it would delete any previous records.
But currently, it doesn't allow me to insert anything it, because it's instantly deleted.
DELIMITER $$
CREATE TRIGGER test_insert
BEFORE INSERT ON test
FOR EACH ROW BEGIN
DELETE FROM test WHERE id = NEW.id - 1;
END$$
How would I delete a previously (or all previous) inserted record?
"But currently, it doesn't allow me to insert anything it, because it's instantly deleted."
Acutally, when you do an INSERT, the execution of your trigger should be throwing exception:
Error Code: 1442
Can't update table 'test' in stored function/trigger because it is
already used by statement which invoked this stored function/trigger.
(Unless something is radically different in a newer version of MySQL.)
The operation you want to perform (i.e. deleting rows from the same table you are inserting into) cannot be done in a MySQL trigger.
You could use a combination of a UNIQUE KEY and a BEFORE INSERT trigger to prevent more than one row from being inserted. The BEFORE INSERT trigger could set the value of the column that has a unique
key on it to be a static value, then the INSERT statement would throw a duplicate key ("Duplicate entry") exception.
Then, you could use an INSERT ... ON DUPLICATE KEY UPDATE ... statement to update the values of columns other than the unique id, e.g.
CREATE TRIGGER `test_insert` BEFORE INSERT ON test
FOR EACH ROW BEGIN
SET NEW.id := 1;
END
ALTER TABLE test ADD UNIQUE KEY (id);
INSERT INTO test (somecol) VALUES ('someval')
ON DUPLICATE KEY UPDATE somecol = VALUES(somecol) ;
To do that you first need to find some value at which you want to delete all and insert for. This way you don't need a trigger, you simply delete all previous cases and then add a new row. Unless for some reason unexplained from your code you would need a trigger a simple solution in your loop could work Like:
$query = mysql_query("DELETE FROM test WHERE id = NEW.id -1");
$new_id = $new.id -1;
$query2 = mysql_query("INSERT INTO test VALUES('$new_id','$var1','$var2'));
Related
I have an application, which cannot update rows, only insert them, but If something is already inserted into the database and it tries to insert a row, it generates a duplicate key error.
I tried to create a trigger for the underlying database table, so If it tries to insert a row that exists, it changes to update instead.
Something like this:
CREATE DEFINER = CURRENT_USER TRIGGER `Test`.`Job_BEFORE_INSERT` BEFORE INSERT ON `Job` FOR EACH ROW
BEGIN
INSERT INTO Job(id, createdAt, updatedAt, `name`,
version, ...)
VALUES(NEW.id, NEW.createdAt, NEW.updatedAt, NEW.name,
NEW.version, ...)
ON DUPLICATE KEY UPDATE
updatedAt=CURRENT_TIMESTAMP, `name`=VALUES(`name`), version=VALUES(version), ...;
END
But it generates an error on the first insert:
Error Code: 1442. Can't update table 'job' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
I read that you can't change the same table in a trigger or a stored procedure. Am I trying to make something impossible? Changing an insert into to an update if the row is existing?
I created the following trigger in Mysql:
DELIMITER //
CREATE TRIGGER delete_G8_dados_indicadores_antes_insert
BEFORE INSERT
ON G8_dados_indicadores FOR EACH ROW
BEGIN
delete from G8_dados_indicadores where id_indicador=NEW.id_indicador and ano = NEW.ano;
END; //
DELIMITER ;
The idea is that before entering a record in G8_dados_indicadores table, the system triggers the trigger automatically removing existing records. But to run an insert, mysql returns the following error:
1442 - Can't update table 'G8_dados_indicadores' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
What can it be?
This is a known limitation in mysql, you have to find a workaround. In this particular instance, I would not even use a trigger, but either use replace into ... or insert ... on duplicate key update ... instead of an insert.
Replace into deletes the old row and inserts the new one, insert ... on duplicate key update ... does an update instead of an insert, if the record already exists.
I'm using Mysql in phpMyAdmin,where i have to delete a entry from tableA if i insert a row with same primary key.I thought to do it in trigger of tableA BEFORE INSERT
For Ex,
if the tableA contains
1 Hai Hello
here 1 is the primary key
And now if i insert a row 1 Bye Hello then the trigger BEFORE INSERT will delete the old entry and then the new row (2nd) will be inserted. But Mysql has restriction of not being able to update a table inside a trigger defined for that same table.
It gives the error
#1442 - Can't update table 'tableA' in stored
function/trigger because it is already used by statement which invoked
this stored function/trigger.
So i changed my way, i called a procedure from trigger BEFORE INSERT of tableA and in that procedure i do the task what i thought to do in trigger. But unfortunately i'm getting the same error.
In trigger BEFORE INSERT i simply called the procedure as
CALL proce1(new.Reg_No);
In procedure i have done this
DECLARE toup integer;
select count(*) into toup from tableA where Reg_No=reg;/*Here Reg_No is primary key */
if toup > 0 then
delete from tableA where Reg_No=reg;
end if;
Need some other Idea to achieve this. Help Me.....
I don't like to use triggers so much because they are hard to manage somethimes. Also they will cause you a downgrade in performance. I am not against trigger as they can be handy in some cases.
In your case have you though of using REPLACE(....) or INSERT INTO .... ON DUPLICATE KEY UPDATE or even INSERT INTO IGNORE .....
REPLACE(....) will delete a record if a record is found and insert a new one with the same ID.
INSERT INTO .... ON DUPLICATE KEY UPDATE will allow you to override existing field if a duplicate is found.
INSERT INTO IGNORE ..... will allow you to ignore the new inserted row if one already exists
Since you mentioned in the comments that you are importing records from a file, then try to use LOAD DATA INFILE logic which will allow you to REPLACE field on duplicate
LOAD DATA LOCAL INFILE 'x3export.txt'
REPLACE INTO TABLE x3export
How can I Update column value to Old value plus New value from other table using Trigger if that value has already have an entry?
What I wanted is something like the following. Notice the bold and italicized part.
DELIMITER$$
CREATE TRIGGER trigger_name AFTER INSERT
ON table_one FOR EACH ROW
BEGIN
INSERT INTO table_two(clmn_id, clmn_one) VALUES(NEW.clmn_id_fk,NEW.clmn_a)
ON DUPLICATE KEY UPDATE clmn_one = VALUES(clmn_one + NEW.clmn_a);
END$$
DELIMITER;
Try removing the keyword VALUES from the ON DUPLICATE KEY:
DELIMITER$$
CREATE TRIGGER trigger_name AFTER INSERT
ON table_one FOR EACH ROW
BEGIN
INSERT INTO table_two(clmn_id, clmn_one) VALUES(NEW.clmn_id_fk,NEW.clmn_a)
ON DUPLICATE KEY UPDATE fine_amount = clmn_one + NEW.clmn_a;
END$$
DELIMITER;
Looks like you need a select statement first, to check if it already exists. If so, set variables to current values, then run an update that combines the old values (variables) and new values. If the record doesn't already exist, run insert statement with current values.
I have the following trigger:
CREATE TRIGGER sum
AFTER INSERT
ON news
FOR EACH ROW
UPDATE news SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
It sums the int_views and ext_views column of a table and divides them by the total pageviews.
Whenever I try to add a new row to news, I get the following error:
ERROR 1442 (HY000) at line 3: Can't update table 'news' in stored function/trigger because it is already used by statement which invoked this stored function/trigger.
The trigger seems pretty simple to me. Is there a reason why the trigger fails to run?
The symptom is, that you are running an UPDATE (for all rows) inside a INSERT trigger - both modify the table, which is not allowed.
That said, if I guess the intention of your trigger correctly, you do not want to update all rows, but only the newly inserted row. You can achieve that easily with
CREATE TRIGGER sum
BEFORE INSERT
ON news
FOR EACH ROW
SET NEW.sum = (NEW.int_views + NEW.ext_views)/NEW.pageviews
Mind that this is a BEFORE INSERT trigger, as you want to change the row before it is written to the table.
If you try to update/insert on the same table that cause trigger to fire do not use the common sql command like
-> UPDATE TABLE_NAME SET COLUMN_NAME = VALUE WHERE CONDITION_LIST;
-> INSERT INTO TABLE_NAME VALUES("VALUE1","VALUE2");
This will not work. Only use set to assign the value of the column you update.
Example:
CREATE TRIGGER trigger_name BEFORE/AFTER INSERT/UPDATE ON table_name
FOR EACH ROW
SET NEW.COLUMN_NAME = "VALUE";
I was in a similar condition where I had to run two triggers:
UPDATE 3 fields on INSERTing a new ROW
UPDATE 3 fields on UPDATEing a ROW
After lot of efforts, I was finally able to write the TRIGGER in following way:
FOR updating values on INSERT
CREATE TRIGGER `INSERT_DISCOUNT_SERVICES` BEFORE INSERT ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)
Similarly
FOR updating values on UPDATE
CREATE TRIGGER `UPDATE_DISCOUNTS_SERVICES` BEFORE UPDATE ON `services`
FOR EACH ROW SET
NEW.discount_5_rate = (NEW.ndis_rate*0.05),
NEW.discount_10_rate=(NEW.ndis_rate*0.10),
NEW.discount_15_rate=(NEW.ndis_rate*0.15)