Update or insert mysql - mysql

I am trying to find a solution to update or insert value in my MySQL table (like in firebird you have UPDATE OR INSERT INTO TABLE (COL1, COL2, COL3) VALUES (VAL1, VAL2, VAL3) MATCHING (COL1, COL2).
I know MySQL have on duplicate key but I do not want that! I do not want to set a key on some of my columns because that one table is used depending on the situation.
So is there any other way of performing update or insert action?

if I remember correctly COL1 should be unique
INSERT INTO table
(COL1, COL2, COL3)
VALUES
(?, ?, ?)
ON DUPLICATE KEY UPDATE
COL2 = VALUES(COL2)
COL2 = VALUES(COL2 )

Related

How to insert values into a table according to the index values of columns in MySQL database?

I want to add values according to index in my table.
This is the code I am trying right now.
insert into A(1,2) values ('ABC','CBA');
The insert statement does not accepts column indexes, but column names. Say your table called a has three columns called id, col1 and col2, and you want to insert into the last two columns, you would do:
insert into a (col1, col2) values('ABC', 'CBA');
The only way that you can add columns according to position is to leave out the column list and include all columns:
insert into A
values ('ABC', 'CBA');
That said, you really should be explicit about which columns are getting values, by including the column names:
insert into A (col1, col2)
values ('ABC', 'CBA');
Or using the MySQL set extension:
insert into A (col1, col2)
set col1 = 'ABC', col2 = 'CBA';

SQL insert list of values in one column dynamicallly

I would like to execute a insert query once for inserting multiple list of records in one column
INSERT INTO Table (col1, col2, col3)
VALUES (val1, val2, listVal3);
The third column only is the list
listVal3 is a list of ids from request
Is it possible to execute to a query like above to insert multiple records
in one column dynamically, if so please help me, thanks.
Maybe you want to create several records having the same values in the first two columns and taking the third column values from table request? In that case the following statement might be useful:
INSERT INTO Table (col1, col2, col3)
SELECT 'val1', 'val2', id from request
WHERE ... --- (some conditions)
You can concat the listVal3 values.
INSERT INTO `tmp_tbl2` (col1, col2, col3)
VALUES (val1, val2, (SELECT GROUP_CONCAT(id) FROM request WHERE ....))

insert on duplicate key update batch with separate update columns

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?
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 :)
The number of fields in VALUES must be the same as in INSERT. But you can just pass NULL for the col4 and use COALESCE in the UPDATE part.
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)
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)
;

How to insert data from one table to anther table?

I have two tables,
tblA(id, num, col1, col2, col3),
tblB(col1, col2, col3)
col1, col2 and col3 are the same in both tables. Now I have following sql:
declare #num...(same type as num)
insert into tblA
select #num, * from tblB
id in tblA is an indentity column.
But I got following error,
Column name or number of supplied values does not match table definition.
Can anyone help me to fix it?
Can you please try providing the column names as well,
declare #num...(same type as num)
insert into tblA(num, col1, col2, col3)
select #num, * from tblB
Please don't worry about identity column as it will get filled automatically.
Just INSERT using named columns, and skip the identity column - it will be filled automatically:
INSERT INTO tblA (num, col1, col2, col3) SELECT #Num, col1, col2, col3 FROM tblB
I think the error message is quite explicative: the SELECT and the INSERT has to have the same number of columns.
in your case
declare #num...(same type as num)
insert into tblA(num,col1, col2, col3)
select #num,col1, col2, col3 from tblB
if the key on tblA is not auto-generated you have to consider it in the INSERT
more info here
It simply based on your column name they should be of same type:
insert into tblA(col1,col2,col3)
select col1,col2,col3
from tblB

Update if one of the values exist, else insert

How can I at an insert query, check if a specific column has a specific value and then update the row. Otherwise it should insert a new row.
Somethings like this is what I want:
INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3) UPDATE IF col3 = $number
Create a UNIQUE key over your col3:
ALTER TABLE `table` ADD UNIQUE KEY (col3)
Then use INSERT ... ON DUPLICATE KEY UPDATE:
INSERT INTO `table` (col1, col2, col3) VALUES (val1, val2, val3)
ON DUPLICATE KEY UPDATE col1 = VALUES(col1), col2 = VALUES(col2)
Have a look at the REPLACE INTO command (MySQL docu).
REPLACE INTO table (col1, col2, col3) VALUES (val1, val2, val3);
It checks primary keys and unique indexes and when there is a matching entry already present, that row is replaced by the new one, else a new row is inserted.
EDIT
As #eggyal mentioned this the behaviour in the case, when the row is replaced, is actually a deletion of the old row and insertion of the new row afterwards. This may lead to some problems, when you're using triggers, foreign keys or alike.
Actually you might loose the content of some columns as well. Suppose you have a table with 3 columns (col1 to col3), but the REPLACE just sets two of them (col1, col2), the third one col3 will receive the default value specified and not retain the old value.
if you have unique index on that column then use this
INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)
ON DUPLICATE KEY UPDATE col3 = $number