MYSQL trigger see if record exists first? - mysql

So I have a trigger that works on update. Totally works fine.
Insert in cars(date, id, parent_id) values (date, ford, 2)
What I need to do is to actually check to see if the parent_id already exists. If it does do nothing but if it does not exist then do the insert statement.
right now i have
SET #myVar1 = (SELECT parent_id from cars where parent_id = NEW.id);
IF #myVar1 = NULL;
Insert in cars(date, id, parent_id) values (date, ford, 2);
ENDIF;
I keep getting sysntax error. How am I writing this worng?

The problem is on this line:
Insert in cars(date, id, parent_id) values (date, ford, 2);
The in should be INTO. That's the syntax error.
That said, you might be better served with an INSERT...ON DUPLICATE KEY or REPLACE INTO statement rather than an on-update trigger. Be careful with REPLACE INTO though, as it can be dangerous (but the danger can be somewhat mitigated by using transactions).

dunno if this what you really need. but you can try this one
SET #myVar1 = (SELECT parent_id from cars where parent_id = NEW.id);
IF (#myVar1 is NULL) then
Insert into cars(`date`, id, parent_id) values (date(), new.`name`, new.id);
END IF;
or
Insert into cars(`date`, id, parent_id) values (date(), new.`name`, new.id) on duplicate key update `date`=date();
on mysql must be "end if" not "endif".
new.name is assumes that id field on car from trigger table
you can use on duplicate key update if cars table use primary key or unique key like mention above
and if you doesn't want to change any record if exists then after key update change to id=id or you can use any field.

Related

What will be the insert query depends on previous data in same table?

I want to insert a row if it's one specific column value is not still available. If available, i want to update that row. Otherwise it will insert normally. What should be the SQL query for this task?
For example:
id, Product_id, user_id, quantity are the table's attributes
Considering,
[1, 450, 56, 2] is in table.
If i want to insert [2,450,56,3] then it will not create new row. It will update the previous row. Like [1,450,56,5].
I'd start by creating a unique constraint on the combination of product_id and user_id (or even a primary key if you don't have one on the table yet):
ALTER TABLE mytable
ADD CONSTRAINT uc_product_user UNIQUE (product_id, user_id);
And then you can use the on duplicate clause in an insert statement:
INSERT INTO mytable
VALUES (2, 450, 56, 3)
ON DUPLICATE KEY UPDATE quantity = quantity + VALUES(quantity);
You could set product_id and user_id as the primary key or unique key on the table and then use INSERT .. ON DUPLICATE KEY UPDATE. You can find more information about that here.
It would look something like:
INSERT INTO t1 (id, product_id, user_id, quantity) VALUES (2,450,56,3)
ON DUPLICATE KEY UPDATE quantity = quantity + 3;
Alternatively, you're going to have to write your own merge statement (MySql doesn't support merge, but you can fake it)
DELIMITER $$
CREATE DEFINER=`root`#`localhost` PROCEDURE `sp_updateValue`(IN prm_productid INT, IN prm_userid INT, IN prm_quantity INT)
BEGIN
-- Check that the case actually exists first.
DECLARE vExists INT;
SELECT COUNT(1) INTO vExists FROM YourTable WHERE product_id = prm_orderid AND user_id = prm_userid;
IF vCaseExists = 1 THEN
UPDATE YourTable SET quantity = prm_quantity WHERE product_id = prm_orderid AND user_id = prm_userid;
ELSE
INSERT INTO YourTable (id, product_id, user_id, quantity) VALUES (2,450,56,3);
END IF;
END$$
DELIMITER ;

"ON DUPLICATE KEY UPDATE" is not working for multiple columns

Executing the query for the first time is working fine for inserting multiple column records but ON DUPLICATE KEY UPDATE is not working for the same records if that query is executed again. It inserts the same value again.
** First value '2' is the primary key auto-incremental **
INSERT INTO info(id, docid, deptid, catid, name)
VALUES (2,5,2,2,'John Adison')
ON DUPLICATE KEY UPDATE docid = concat(docid,',',5), deptid = concat(deptid,',',2), catid = concat(catid,',',2);
the output should be unchanged if it gets same records from all column.
if your intention is to ignore insert (dont make update) when duplicate key found then you can use IGNORE
INSERT IGNORE INTO my_table
( unique_index_column, other_column ) VALUES( 1, 'other value' );
but this has downside that ignores all insert errors. Alternatively you can use
INSERT INTO table_tags (id, docid, deptid, catid, name) VALUES (2,5,2,2,'John Adison')
ON DUPLICATE KEY UPDATE name=name;

Script/workflow insert not exist and auto increment

I create a script/workflow exportation/importation from 2 system.
I have Table1 {id, name, description}
I want to create a script (not a procedure). I could (I didnt succed) adding procedure into my workflow. (create and delete at the end)
id is auto increment
I cant change the table
I can be sure that between the time I start execution of my script and the end, there will not be an insertion of one of my items into the database.
The script insert {name,description} but I want to NOT insert if the element (name or name and description) is there.
BASE QUERY :
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X')
BASE Script :
Use database1;
BEGIN;
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
INSERT INTO TABLE1 (name,description) VALUES ('itemX','this is item X');
set #idTable1 = LAST_INSERT_ID();
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,1);
INSERT INTO TABLE3 (idTable1,idTable2) VALUES (#idTable1,2);
SELECT * FROM TABLE1 ;
SELECT * FROM TABLE3 ;
ROLLBACK;
I want to protect the multiple insertion on TABLE1. But without changing the table.
Maybe I did it wrong
I tried IF but not working outside procedure.
I tried IGNORE (valid only if id is the same, but never the same, its
auto increment)
I tried WHEN
I tried ON DUPLICATE KEY
Because of #idTable1, I will need change the " set #idTable1 = LAST_INSERT_ID();" if I doesnt have if else. But if my item is the only one with the same "name", I can get this instead of last_insert_id.
I opted for creating procedure before my "BEGIN" and removed them at the end of the script.
Just create the table with name as primary key, then be sure that you take care of the key capitalization (uppercase or lowercase) to avoid duplicates.
CREATE TABLE TABLE1(
id INT AUTO_INCREMENT,
name CHAR(30),
description CHAR(100),
PRIMARY KEY (name)
)
create unique constraint on name field if possible.
Otherwise, create trigger before insert in order to ignore duplicate insertion.
Trigger for checking duplicate on two fields a and b:
delimiter //
drop trigger if exists aborting_trigger //
create trigger aborting_trigger before insert on t
for each row
begin
set #found := false;
select true into #found from t where a=new.a and b=new.b;
if #found then
signal sqlstate '45000' set message_text = 'duplicate insert';
end if;
end //
delimiter ;
The trigger here provides feature similar to unique constraint. After creation you should use INSERT IGNORE or INSERT ...ON DUPLICATE KEY UPDATE

Insert if Update row_count()=0

I need to update a table row, but if it dont exist, it must be created.
I´ve tried with that code but returns errors:
UPDATE creature SET name="Bip" WHERE guid = 1;
IF ROW_COUNT()=0 THEN
INSERT INTO creature (guid, name) VALUES(1, "Bip");
END IF;
I need to update before inserting, so i cant use "INSERT … ON DUPLICATE KEY UPDATE …"
Thats becouse i supose that Insert query will be skiped if ROW_COUNT is 0.
What can i do to fix it?
You can do this with INSERT ... ON DUPLICATE KEY:
INSERT INTO creature (guid, name) VALUES (1, "Bip")
ON DUPLICATE KEY UPDATE name=VALUES(name)
That should insert a new row, or if there's a collision on guid, then it'll update the name.
Note you need to have a UNIQUE index on guid for this to work. If there's no UNIQUE constraint then it will insert duplicates.

INSERT INTO if NOT EXISTS or increment if EXISTS

My question is. I have the table 'popular' with fields 'id', 'title', 'popularity' in MySQL. I need insert info into field "title", if info not exists or increment value of 'popularity', if info exists. What is the best practice to do it?
INSERT ... ON DUPLICATE KEY UPDATE Syntax
INSERT INTO popular (title, popularity) VALUES (:the_title, 1)
ON DUPLICATE KEY UPDATE id = LAST_INSERT_ID(id), popularity = popularity + 1
Make sure you have an unique constraint on title
id = LAST_INSERT_ID(id) allows you to get the id of the record you inserted/updated using LAST_INSERT_ID (or the equivalent function for your MySQL API). If you don't need the id you can remove it from the UPDATE list.
sample code:
if exists (select * from contact where name = #name) then
select -1;
else
insert into contact(name) values(#name);
select last_insert_id();
end if;
reference:
http://ask.sqlservercentral.com/questions/88038/best-mysql-practice-to-insert-a-record-if-it-does.html
http://bugs.mysql.com/bug.php?id=19243
http://mikefenwick.com/blog/insert-into-database-or-return-id-of-duplicate-row-in-mysql/