I have a situation where I have a table (col1 (pk), col2, col3, col4) and a set of records which I need to insert into a table and on duplicate key update them. I would like to do a batch query to speed things up. However, col4 doesn't have a NOT NULL constraint. The problem arises when I want to update with records (val1, val2, val3, None), (val4, val5, val6, val7). For the first record, I don't want column 4 to be updated (If (val1, val2, val3, val8) existed in DB I wouldn't want to override val8 because None would signify lack of value as opposed to explicit setting to Null). However, for the second record, I would want to update col4 because an explicit value is passed. This would be fine with one record where I would just set the update columns to be col2, col3, and not col4, but I want to batch this query and would need to have col4update when a value is passed for it and not update when I don't have a value. I would logically need something like given below.
INSERT INTO table1
(col1, col2, col3, col4)
VALUES
('val1', 'val2', 'val3'), ON DUP KEY UPDATE col2, col3
('val5', 'val6', 'val7', 'val8'), ON DUP KEY UPDATE col2, col3, col4
('val9', 'val10', 'val11') ON DUP KEY UPDATE col2, col3
Clearly this can be done by just making it a series of separate statements, but I would like to find a way to batch this. Is there any way this, or a different method, can be done in sql?
Is this the thing that you are looking for?
INSERT INTO table1
(col1, col2, col3, col4)
VALUES
('val1', 'val2', 'val3', null)
('val5', 'val6', 'val7', 'val8')
('val9', 'val10', 'val11', null)
ON DUPLICATE KEY UPDATE
col2 = values(col2),
col3 = values(col3),
col4 = coalesce(values(col4), col4)
;
In the on duplicate key update part of the insert, you can refer to the inserted values with values. You can use coalesce to preserve the pre-update value in case of null:
INSERT INTO YourTable (col1, col2, col3, col4) VALUES
('val1', 'val2', 'val3', null)
, ('val5', 'val6', 'val7', 'val8')
, ('val9', 'val10', 'val11', null)
ON DUPLICATE KEY UPDATE
col1 = values(col1)
, col2 = values(col2)
, col3 = values(col3)
, col4 = coalesce(values(col4), col4)
Example on SQL Fiddle.
In reply to your comment, you can set null explicitly with a case:
, col4 = case values(col4)
when 'None' then null
else coalesce(values(col4), col4)
end
The obvious risk here is that you can no longer update to None :)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With