Reputation: 1805
I would like to combine insert/update with a case statement, meaning that I want to insert the row if it doesnt exist, update it if it does, but in both cases with different values (when updating it depends on the id) and when inserting, well then I set it...
And this should happen in a single SQL statement :-)
In a nutshell: I am trying to combine these two statements into a single one:
1). Insert/Update:
MERGE INTO table_name USING dual ON (id='{id}')
WHEN MATCHED THEN UPDATE SET {col1}='{val1}', {col2}={val2}
WHEN NOT MATCHED THEN INSERT ({id}, {col1}, {col2}) VALUES ('{id}', '{val1}', {val2})
2). Update different values with case:
UPDATE SIGNALVALUE
SET
SIGNUMVALUE = CASE SIGID
WHEN 49634 THEN 1.1
WHEN 49674 THEN 2.2
WHEN 49675 THEN 1.8
END,
UPDATETIME = CASE SIGID
WHEN 49634 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
WHEN 49674 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
WHEN 49675 THEN TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR')
END
WHERE SIGID IN (49634, 49674, 49675)
These statements are just examples. In reality there are many more rows to insert/update and this happens frequently so I am trying to minimize the amount of queries.
Also I cannot do update and then see how many rows were affected and then insert the ones that werent because I will not know the IDs of the rows that need to be inserted vs the ones that need to be updated. At least as far as I understand...please correct me!
Upvotes: 0
Views: 4618
Reputation: 1805
MERGE INTO SIGNALVALUE USING (
SELECT 49674 as SIGID,
TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
'777' as SIGNUMVALUE
FROM dual
UNION ALL
SELECT 49675 as SIGID,
TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
'777' as SIGNUMVALUE
FROM dual
UNION ALL
SELECT 49676 as SIGID,
TO_TIMESTAMP_TZ('2011-03-18 18:24:56:00', 'YYYY-MM-DD HH24:MI:SS:FF6 TZR') AS UPDATETIME,
'777' as SIGNUMVALUE
FROM dual
) n
ON(SIGNALVALUE.SIGID = n.SIGID)
WHEN NOT MATCHED THEN
INSERT (SIGID, SIGNUMVALUE, UPDATETIME) VALUES (n.SIGID, n.SIGNUMVALUE, n.UPDATETIME)
WHEN MATCHED THEN
UPDATE SET SIGNUMVALUE=n.SIGNUMVALUE, UPDATETIME=n.UPDATETIME
Upvotes: 0
Reputation: 12833
It doesn't have to be a table in the using
clause, you can also use a SQL query.
At least that is what I think you are after :)
merge
into target_table
using (select case when ... then ... else ... end as id
from dual
) source_table
on(target_table.id = source_table.id)
when matched then
update
set ...
when not matched then
insert (...)
values (...)
Let me know if that helps. If so, I can probably help write the final query as well.
Upvotes: 3