I got MySQL update query like this :
"INSERT INTO $tbl_name
(status, name, ...)
VALUES
('$status', '$name'...)
ON duplicate KEY UPDATE
status=values(status), name=values(name)...
";
It have a lot of table columns so to keep it short I`ll get right to the issue:
Instead of updating the current table row it duplicates it with a new ID.
Note : There are unique fields in the row. Any ideas what am I doing wrong ?
Check existence before doing any Insert/Update
IF (SELECT 1 = 1 FROM Table WHERE Key=...) THEN
BEGIN
UPDATE Table Set status=values(status), name=values(name)... WHERE Key=...;
END;
ELSE
BEGIN
INSERT INTO Table (FieldValue) VALUES('');
END;
END IF;
Why not to use
UPDATE table_name
SET column1=value1,column2=value2,...
WHERE some_column=some_value;
?
Related
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
I'm using MySQL Workbench (6.3) and I'm trying to create a stored procedure with a specific "INSERT IF NOT EXSISTS" but I think I don't do it well. By the way, I did read this topic http://bogdan.org.ua/2007/10/18/mysql-insert-if-not-exists-syntax.html and tried both examples, it didn't work. Here is the statement :
CREATE DEFINER=`test`#`localhost` PROCEDURE `onPlayerJoin`(
IN uuid CHAR(36),
IN nickname CHAR(16),
IN firstConnection TIMESTAMP,
IN lastConnection TIMESTAMP
)
BEGIN
INSERT IGNORE INTO `test`.`player` (`playerUuid`, `playerNickname`, `playerFirstConnection`, `playerLastConnection`)
VALUES (uuid, nickname, firstConnection, lastConnection);
UPDATE `test`.`player` SET
`playerNickname` = nickname,
`playerLastConnection` = lastConnection
WHERE `playerUuid` = uuid;
END
IF the PK isn't found, INSERT it. ELSE, UPDATE certain columns. (that I can specified) However, it seems that it updates every column, which I would like to restrict to certain columns. Here is my procedure : http://pastebin.com/NfcdU9Rb !
Optional question : is it injection-safe ?
Use INSERT ... ON DUPLICATE KEY UPDATE Syntax
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Kindly refer the link for details:
http://dev.mysql.com/doc/refman/5.6/en/insert-on-duplicate.html
Based on my previous post found here im able to insert the values to the 2nd table when the status on first table changes, but it keeps adding indiscriminately, i need to check if the submit_id has already been inserted into the 2nd table and then update the fields not insert it gain, how would i do that check before the trigger is executed?
Because the new.status and old.status refer to the row being edited not the row on table it's being inserted into, how can i compare that and insert or update if it already exists,
Thanks
You can use INSERT INTO ... ON DUPLICATE KEY UPDATE syntax for that
If order for it to work properly you have to have a UNIQUE constraint on submitId column in your second table (let's call it students).
ALTER TABLE students ADD UNIQUE (submitId);
Now an improved version of a trigger
DELIMITER $$
CREATE TRIGGER tg_au_submissions
AFTER UPDATE ON submissions
FOR EACH ROW
BEGIN
IF NEW.status = 1 THEN
INSERT INTO students (submitId, studentName, submitDate, contacts, email)
VALUES (NEW.submitId, NEW.studentName, NEW.submitDate, NEW.contacts, NEW.email)
ON DUPLICATE KEY UPDATE
studentName = VALUES(studentName),
submitDate = VALUES(submitDate),
contacts = VALUES(contacts),
email = VALUES(email);
END IF;
END$$
DELIMITER ;
Here is SQLFiddle demo
I created a trigger like:
CREATE TRIGGER `update_tb2` AFTER UPDATE ON `table_1` FOR EACH ROW
IF new.parameter = 'param1'
THEN UPDATE table_2 SET table_2.input = '10' WHERE table_2.key = '0';
END IF ;
It works as expected, when I update any row in the table_1 the one with key=0 in the other table is updated.
Since there is a field key in both tables, I want to update in the second table to row who has the same key of the updated row in table_1. I can't figure out how to use table_2.key inside the IF block.
You can use the new or old keyword (in case you change the key value, you may want to use one or the other). It let's you access all the values from the record that was updated on table_1:
CREATE TRIGGER `update_tb2` AFTER UPDATE ON `table_1` FOR EACH ROW
IF new.parameter = 'param1'
THEN UPDATE table_2 SET table_2.input = '10' WHERE table_2.key = new.key;
END IF ;
You can see an example on this fiddle
try this:
CREATE TRIGGER `update_tb2` AFTER UPDATE ON `table_1` FOR EACH ROW
IF new.parameter = 'param1'
THEN UPDATE table_2 SET table_2.input = '10' WHERE table_2.key = old.key;
END IF ;
I just want to store records in two way.
If it exists, it will update information
If it dosn't exist, it will insert as new record
Here are the outline schemas for my tables:
product_purchase_item has product_purchase_item_id, product_id, quantity columns
product_stock has product_stock_id, product_id, product_total_quantity columns
I was creating a trigger
DELIMITER //
CREATE TRIGGER store_check AFTER INSERT ON product_purchase_item
FOR EACH ROW
BEGIN
DECLARE X INTEGER;
SET X =(SELECT product_id FROM product_stock where product_id = NEW.product_id);
IF NEW.product_id !=X THEN
INSERT INTO product_stock VALUES(NULL,NEW.product_id,NEW.quantity);
ELSE
UPDATE product_stock
SET product_total_quantity=product_total_quantity+NEW.quantity
WHERE product_id=NEW.product_id;
END IF;
END;//
DELIMITER;//
The problem is in product_stock table, INSERT query doesn't work when product record not exist, but update query work does properly when product record does exist.
Is it really the INSERT statement that "doesn't work"? Or, is the problem that the INSERT statement is not being executed at all?
What happens when the preceding SELECT query does not return a row? What value gets assigned to X?
When X has that value, does a conditional test "foo != X" return TRUE, or does it return something else (like FALSE, or NULL)?
Have you tried something like this?
IF NEW.product_ID = X THEN
UPDATE ...
ELSE
INSERT ...
END IF;
(I know it's bad practice to answer a question with a question; but it seemed apropros, since answering those will get you the answer to the question you really wanted to ask.)
You can do the desired operation through one of MySQL's standard commands:
INSERT INTO product_stock (product_id,product_total_quantity)
VALUES (NEW.product_id,NEW.quantity)
ON DUPLICATE KEY UPDATE product_total_quantity=product_total_quantity+NEW.quantity;
see the MySQL manual