IF Exists Then Update MySQL - mysql

I am trying to update a row if its exists, if it does not exist then I want to perform an insert into the table. The picture.id & picture.picturepath are a unique key. I have looked at some examples but I am not sure What I am doing wrong.
I have come across on duplicate key update, not sure if this is relevant to what I am trying to achieve.
Error message: 1064- You have an error in your SQL syntax near 'UPDATE picture SET picture.picturecontent = ipicturecontent WHERE picture.id at line 5"
IF EXISTS( SELECT * FROM picture WHERE picture.id = ipictureid
AND picture.picturepath = ipicturepath) THEN
UPDATE picture
SET picture.picturecontent = ipicturecontent
WHERE picture.id = ipictureid
AND picture.picturepath = ipicturepath
ELSE
INSERT INTO picture (picture.id, picture.picturecontent,picture.picturepath) VALUES (ipictureid, ipicturecontent, ipicturepath)

https://stackoverflow.com/a/10095812/1287480 <- Credit where credit is due
INSERT INTO models (col1, col2, col3)
VALUES ('foo', 'bar', 'alpha')
ON DUPLICATE KEY UPDATE col3='alpha';

don't forget THEN, BEGIN and END
IF EXISTS( SELECT * FROM picture WHERE id = ipictureid
AND picturepath = ipicturepath)
THEN
BEGIN
UPDATE picture
SET picturecontent = ipicturecontent
WHERE id = ipictureid
AND picturepath = ipicturepath
END;
ELSE
BEGIN
INSERT INTO picture (id,
picturecontent,
picturepath)
VALUES (ipictureid, ipicturecontent, ipicturepath)
END;
END IF;

Related

Select into statement for null or more than one value

I am stuck in plsql , as I have making function in which I have to update a table if only values comes in select into ..
and if not come then not and if multiple comes then have to update and delete for all that values .
In below function if in first select into null value comes then should not goto exception handling should update only CUSTOMER table and only delete from table 3 ,, if one or many values comes then do all update and delete for each value
create or replace FUNCTION FUNCTION_NAME (
from_PARTICIPANT_KEY1 IN NUMBER
)
RETURN
IS
to_participant_key1 NUMBER (11);
BEGIN
SELECT to_participant_key
INTO to_participant_key1
FROM TABLE2
WHERE FROM_PARTICIPANT_KEY = from_PARTICIPANT_KEY1;
UPDATE CUSTOMERS C
SET C.CUSTOMER_STATUS_CD =
NVL (
(SELECT old_status_cd
FROM TABLE1
WHERE PARTICIPANT_UID = from_PARTICIPANT_KEY1
AND participant_cd = 'CUSTOMER'),
C.CUSTOMER_STATUS_CD
)
WHERE C.CUSTOMER_UID = from_PARTICIPANT_KEY1;
UPDATE subscribers C
SET C.STATUS_CD =
NVL (
(SELECT old_status_cd
FROM TABLE1
WHERE PARTICIPANT_UID = to_participant_key1
AND participant_cd = 'SUBSCRIBER'),
C.STATUS_CD
)
WHERE C.account_no = to_participant_key1;
DBMS_OUTPUT.PUT_LINE ('Delete TABLE1 rows');
DELETE FROM TABLE3
WHERE PARTICIPANT_UID = from_PARTICIPANT_KEY1 AND participant_cd = 'CUSTOMER';
DELETE FROM TABLE1
WHERE PARTICIPANT_UID = to_PARTICIPANT_KEY1 AND participant_cd = 'SUBSCRIBER';
COMMIT;
EXCEPTION -- exception handlers begin
WHEN NO_DATA_FOUND THEN -- handles 'division by zero' error
dbms_output.put_line('Customer not found ' || from_PARTICIPANT_KEY1);
WHEN OTHERS THEN -- handles all other errors
dbms_output.put_line('Some other kind of error occurred.');
END;
You can use BULK COLLECT INTO and iterate over collection.
First of all, you have to declare (or use some existing) collection type and create the variable of this type:
TYPE participant_keys is table of number (11);
l_participant_keys participant_keys;
Then, your query will change to:
SELECT to_participant_key
BULK COLLECT INTO to_participant_key1
FROM TABLE2
WHERE FROM_PARTICIPANT_KEY = from_PARTICIPANT_KEY1;
If the query will not return any record then you can check it with COUNT:
if l_participant_keys.COUNT = 0 then
-- update only CUSTOMER table and only delete from table 3
else
FOR I IN l_participant_keys.FIRST .. l_participant_keys.LAST LOOP
--use l_participant_keys(i) do all update and delete for each value
END LOOP;
end if;

During Update Perform For Each On Last Insert ID

I have a very simple procedure which performs an update on multiple rows. Is their a way I can loop through the insert id of each updated row?
BEGIN
UPDATE testTable set testValue = 2
where username = inputUser and flag = 1;
//for each update performed, insert LAST_INSERT_ID() into tableB
END
is this possible? If so, can you lead me in the right direction?
LAST_INSERT_ID only gives you one last id. You can do multiple inserts without a loop. You can use the output of SELECT query and insert to the desired table. You can do something like that:
BEGIN
UPDATE testTable set testValue = 2
where username = inputUser and flag = 1;
INSERT into tableB (column1, column2)
SELECT column1, column2 FROM testTable
WHERE username = inputUser and flag = 1;
END
For example:
User (username, password)
UserLoginLog (username, last_log_in_date)
INSERT INTO UserLogInLog (username, last_log_in_date)
SELECT username, NOW()
FROM User
WHERE username = "JohnDoe"

cant insert data in mysql

So I'm trying to do a trigger in mySQL that looks like:
on table:likes, event:after insert
IF NEW.action` = 1 THEN
INSERT IGNORE INTO matches
(user_id, user_id_friend)
(SELECT user_id_from, user_id_to
FROM likes
WHERE user_id_from = NEW.user_id_to AND user_id_to = NEW.user_id_from AND `action` = 1);
IF (SELECT user_id_from, user_id_to
FROM likes
WHERE user_id_from = NEW.user_id_to AND user_id_to = NEW.user_id_from
AND `action` = 1) IS NOT NULL
THEN
INSERT IGNORE INTO matches
(user_id, user_id_friend)
VALUES
(NEW.user_id_from, NEW.user_id_to);
END IF;
END IF`
the syntax should be right because heidi SQL (the software i'm using) allows me to save it, but when i try to insert something into likes with action = 1, it shows me: MySQL error 1241: Operand should contain 1 column(s)
What am i doing wrong?

MySQL TRIGGER with an IF statement determined by an IN

I'am constructing a trigger
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET #error_msg_id := (SELECT `error_msg_id` FROM `orders_err` WHERE orderID = OLD.orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (100 IN (SELECT #error_msg_id)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
Where I would like to, first see if there is any error_msg_id on the orderID and later use this in the elseif statement to see if a possible error has been completed.
It works if i do this
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF EXISTS(SELECT * FROM orders_err WHERE orderID = OLD.orderID AND error_msg_id = 100) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
But i would like to only call the select once if possible, since i have 12 similar if statements on other columns in the orders_shipping table.
On update i get the error: ERROR 1242: 1242: Subquery returns more than 1 row
Thanks in advance
One of possible solutions is to concatenate ids to one string separated by commas using GROUP_CONCAT(..) function - then first SELECT statement will return one row. To test whether an id is in the string use FIND_IN_SET(..) function:
CREATE TRIGGER `address_control_update` BEFORE UPDATE ON `orders_shipping`
FOR EACH ROW
BEGIN
SET #error_msg_ids = (
SELECT GROUP_CONCAT(DISTINCT `error_msg_id`)
FROM `orders_err`
WHERE orderID = OLD.orderID
GROUP BY orderID);
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSEIF (FIND_IN_SET(100, #error_msg_ids)) THEN
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
END;//
Also I think there exists other possibilities. For example you can write code without SELECT statement:
IF(LENGTH(NEW.ShippingName) = 0 OR NEW.ShippingName IS NULL) THEN
INSERT INTO `orders_err` (orderID,error_msg_id) VALUES(NEW.orderID,100) ON DUPLICATE KEY UPDATE complete=false;
ELSE
UPDATE `orders_err` SET complete = true WHERE orderID = OLD.orderID AND error_msg_id = 100;
END IF;
why - because you use the same filtering conditions in SELECT and in UPDATE - so there no need to test the same conditions before update.

How can i create a trigger that will only update a record if the new record is different from the old record?

Question is create a trigger that will only update a record if the old record is different from the new. Can i get some help please i don't even know how to start the syntax apart from
CREATE TRIGGER update_marketingliste
ON marketing_list FOR UPDATE
AS
BEGIN
SELECT * FROM INSERTED
END
I am not sure what the schema is but the sample code below should help you to understand how this can be done.
SET NOCOUNT ON
GO
CREATE TABLE test(col1 int primary key , col2 int )
go
CREATE TRIGGER trg_test_upd on test
INSTEAD OF UPDATE
AS
BEGIN
IF EXISTS (
SELECT *
FROM Deleted del -- old value
INNER JOIN Inserted ins -- new value
on del.col1 = ins.col1
and del.col2 = ins.col2)
BEGIN
PRINT 'No Update'
RETURN --if old value is same as new value dont update
END
ELSE
BEGIN
UPDATE t1
set col2 = i.col2
from dbo.test t1
inner join inserted i
on t1.col1 = i.col1
END
END
go
Insert into test (col1, col2)
select 10, 10
go
update test
set col2 = 200
where col1 = 10
SELECT *
FROM TEST
--This would not do the update
update test
set col2 = 200
GO
Drop table test
go