I have a database: groupofficecom has two tables:
cal_events: id(Primary key), name, start_time, description,....
cf_cal_events: model_id (Primary key), col_1, col_2, col_3,....
I'm trying to execute the following code:
INSERT INTO groupofficecom.cf_cal_events (model_id,col_1,col_2,....)
SELECT groupofficecom.cal_events.ID, '0' AS col_1, '' AS col_2,....
FROM groupofficecom.cal_events
But it keeps giving me error #1062 - Duplicate entry '155' ('155' is the 'id' from cal_events) for key 'PRIMARY'
I want the primary key model_id to be the same value as id in cal_events because the table cf_cal_events is just complementary fields for cal_events (this is a program, so I can't change its database, it'll be gone on the first update)
Thank you guys!
This means there already is an entry with that id in the target table.
First, check how this can be.
Then, use one of the solutions described here as is appropriate:
"INSERT IGNORE" vs "INSERT ... ON DUPLICATE KEY UPDATE"
i.e. UPDATE or IGNORE.
You should use an ORDER BY with the select you have and the solution above to choose which entries get ignored (all but the first entry with IGNORE).
It is also possible that you want something different entirely, i.e. to use an UPDATE statement instead of an INSERT statement.
In fact I found a very good function, it's very similar to the INSERT but smarter:
REPLACE INTO database (column_1, column_2)
SELECT source_column1, 'value' AS column2
FROM table;
Or:
REPLACE INTO database (column_1, column_2)
VALUES ('value1', 'value2')
FROM table;
Works like magic!
It inserts new items to the destination table, and if it finds a row with the same primary key value, it erases it and re-inserts the new value (it works great for updating a table from another one)
I hope this solves your problem like it solved mine ;)
Related
I have two tables in a Mysql database: "stock_pricing" and "DATA_IMPORT"
columns in first table: STOCK_ID, DATE, LAST_CLOSE_DOM_CURR
columns in second table: STOCK_ID, DATE, ADJ_CLOSE
The first table has an index on stock_id and date together. These have been defined as UNIQUE.
The second table has no index at all.
The second table has incoming data. On this table there is a BEFORE INSERT trigger that inserts incoming data into the first table.
If upon the insert trigger the combination of STOCK_ID and DATE violates the UNIQUE index of the first table, the ON DUPLICATE KEY UPDATE part of the trigger is fired.
I have tried every combination I can think of, but the trigger does not recognise my column names, any thoughts? Many thanks.
BEGIN
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
VALUES (DATA_IMPORT.STOCK_ID, DATA_IMPORT.DATE, DATA_IMPORT.ADJ_CLOSE)
ON DUPLICATE KEY UPDATE
stock_pricing.STOCK_ID= DATA_IMPORT.STOCK_ID, stock_pricing.DATE= DATA_IMPORT.DATE, stock_pricing.LAST_CLOSE_DOM_CURR= DATA_IMPORT.ADJ_CLOSE;
END
You are referencing a table called data_import with no from clause. This is fixed using insert . . . select:
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
SELECT DATA_IMPORT.STOCK_ID, DATA_IMPORT.DATE, DATA_IMPORT.ADJ_CLOSE
FROM DATA_IMPORT
ON DUPLICATE KEY UPDATE
stock_pricing.STOCK_ID= DATA_IMPORT.STOCK_ID, stock_pricing.DATE= DATA_IMPORT.DATE, stock_pricing.LAST_CLOSE_DOM_CURR= DATA_IMPORT.ADJ_CLOSE;
A more typical way of writing such a query is:
INSERT INTO stock_pricing (`STOCK_ID`, `DATE`, `LAST_CLOSE_DOM_CURR`)
SELECT di.STOCK_ID, di.DATE, di.ADJ_CLOSE
FROM DATA_IMPORT di
ON DUPLICATE KEY UPDATE STOCK_ID = VALUES(STOCK_ID),
DATE = VALUES(DATE),
LAST_CLOSE_DOM_CURR = VALUES(LAST_CLOSE_DOM_CURR);
For ON DUPLICATE KEY UPDATE to work, you need a unique index or primary key. I assume you have these.
Finally, this code looks a bit strange for a trigger, because there are no references to NEW or OLD. If you are still having trouble with the trigger, then ask another question and include the full code for the trigger.
I'm using ON DUPLICATE KEY UPDATE to handle duplicate inserts on a table, in order that they are discarded.
In my case it's a simple table storing tags:
id (int, PK, AI, unsigned, not null)
tag (varchar 25, not null, unique)
This is working fine, but I need to retrieve the ID - either the insert ID, on successful insert, or the existing ID, if it's a duplicate.
I'm getting insert ID = 0 where ON DUPLICATE KEY UPDATE fires, which I guess is expected behaviour since no insert took place.
Is there anyway I can get the existing ID, or am I headed to a separate read query?
You could add a third column ModifiedDate and use that:
insert into t(id, tag)
select id, tag
on duplicate key update ModifiedDate = now();
This will ensure that an update really occurs, and in turn, that LAST_INSERT_ID() returns a value.
I'm trying to set a unique restraint on a combination of columns rather than on a single column. I have a table, "tags":
id (int, PK, AI, unsigned)
tag (varchar 25)
user_id (int, unsigned)
Following the answer to this question, I tried to set the combo restraint via:
ALTER TABLE `tags` ADD UNIQUE `unique_tag_user_combo` (`tag`, `user_id`);
So far, so good. But when I come to test it, by seeing if it will let me insert the same tag twice but with different user IDs (it should), it errors:
INSERT INTO `tags` VALUES (NULL, 'foo', '1'), (NULL, 'foo', '2')
...throws...
Duplicate entry 'foo' for key 'name_2'
Remember the unique restraint is on the combo of tag + user_id, so this query, to my mind, should run fine. I could understand this error if I'd tried to insert foo/1 twice, but not foo/1 and foo/2. What am I missing?
(EDIT - also, what's that 'name_2' reference in the error message all about? I don't have a column with that name...)
You might also have an unique index on tag column.Use
SHOW CREATE TABLE yourtb
I have a table with with essentially three columns: user_id, setting, and value. I'm trying to use the following code:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 500)
ON DUPLICATE KEY UPDATE user_id = 1234, setting = setting_1'
This works great when creating a new setting, and it doen't generate duplicate records. The problem comes when I want to change the value- this won't work after the previous query has run:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 999)
ON DUPLICATE KEY UPDATE user_id = 1234, setting = setting_1'
No rows are affected. Clearly I'm missing something...
IMPORTANT: I am not able to alter the database (new primary keys or something).
UPDATE: It seems my understanding of ON DUPLICATE KEY is wrong. But the question remains- what is the most efficient way way to accomplish this?
Answered in a comment below: "If the Primary (or Unique) key is (user_id, setting), then use: ... ON DUPLICATE KEY UPDATE value=999".
Assuming you actually have a unique key on user_id, you are getting "no rows affected" because you aren't changing anything in the second query. I think what you want to do is update the value field as well:
INSERT INTO 'user_settings'(user_id, setting, value)
VALUES (1234, setting_1, 999)
ON DUPLICATE KEY UPDATE setting = setting_1,value=999
Without value in there, you're just setting the user_id and the setting field to the same values they were before, and MySQL doesn't need to update the record.
If you don't have a unique key on user_id, you'll have to find a different approach, as the ON DUPLICATE KEY UPDATE won't trigger.
i'm currently using a replace into statement, I have a unique field which will cause it to UPDATE rather than INSERT if it finds a duplicate...
Problem is if it finds a duplicate i can't get to update on a few columns, it just wipes the lot.
Is there a similar "one statement" method where I can just UPDATE what I want?
I've found merge into but don't undertsnad the first bit about merge into table using table
You're going to want to use the INSERT...ON DUPLICATE KEY UPDATE syntax.
http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html
Here's an example that will try to create a record with an id, birthday, and name. If a record with the id field exists, it will do the update specified. The table has lots of other fields like email address, zip code, etc. I want to leave those fields alone if I update. (REPLACE INTO would lose any of that data if I didn't include it in the REPLACE INTO statement.)
INSERT INTO user (userid,birthday,first_name,last_name)
VALUES (1234,'1980-03-07','Joe','Smith')
ON DUPLICATE KEY UPDATE
birthday = '1980-03-07',
first_name = 'Joe',
last_name = 'Smith';