MySQL on duplicate key... get existing ID? - mysql

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.

Related

insert into 2column table, avoiding duplicate records

I have a table with 2 columns, userid and messageid. I am updating it automatically through a php script, but I can't get a working insert statement. I don't mind if there are duplicates of userid, or duplicates of messageid (in fact there should be duplicates of both), I just don't want any duplicate of the same combination of userid and messageid. Is there any way to write a query that will do this for me, or do I have to handle it at the php level?
I've probably tried 20 different queries that I found on here and google, but have not gotten it right. This was the last thing I tried:
INSERT INTO interests_join (userid, interestid)
VALUES (1, 4)
WHERE NOT EXISTS
(SELECT userid, interestid FROM interests_join WHERE userid = 1 AND interestid = 4)
You can add a UNIQUE KEY, sql will refuse to insert a new row that is a duplicate of an existing one.
ALTER TABLE `interests_join` ADD UNIQUE `row` (`userid`, `interestid`);
Then you'll have to check from PHP if the query was successful or not (error #1062). You can't apply the key if there are duplicate rows, you have to remove them first .

mysql - INSERT... ON DUPLICATE KEY UPDATE, but not really...?

Hi I've been trying to get this to work, I thought I had it with mysql - INSERT... ON DUPLICATE KEY UPDATE, but no luck.
I have a table as such:
sessionID is unique,
productID references another table and is not unique, but not common, should be a max of 3 rows containing the same value,
sessionType is either 1, 2 or 3, and would link with productID,
I need to check if the table has a row where there is a matching pair of productID and sessionType, if there is then sessionDate & sessionCapacity in that row should be UPDATED, if there isn't then a new row inserted.
$vals = array($pID,$data['pSessionDate'],'1',$data['pQty'],$pID,$data['pSessionDate'],'1',$data['pQty']);
$db->Execute("INSERT INTO VividStoreSessions (pID,sDate,sType,sCapacity) VALUES (?,?,?,?) ON DUPLICATE KEY UPDATE pID=?,sDate=?,sType=?,sCapacity=?",$vals);
Hope that makes sense to someone and thanks in advance for any help!
Your insert looks valid. But, first you need a unique index/constraint:
create unique index unq_VividStoreSessions_productId_sessionType
on VividStoreSessions, productId, sessionType)
Then you can write the code to only use four parameters:
INSERT INTO VividStoreSessions (pID, sDate, sType, sCapacity)
VALUES (? ,?, ?, ?)
ON DUPLICATE KEY UPDATE sDate = VALUES(sDate), Capacity = VALUES(Capacity);
Finally, you need to ensure that sType only takes on the values of 1, 2, or 3. Perhaps you want to enforce this at the application layer. Otherwise, you need a trigger or foreign key constraint to ensure that there are only three rows.

MySql Trigger INSERT... ON DUPLICATE KEY UPDATE not recognising columns

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.

INSERT INTO...SELECT - Primary key conflict - error #1062

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 ;)

MySQL: Advanced insert if not exists

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.