Reputation: 10009
I would like to insert data into one of my MySQL tables uniquely. That is, if the very same entry (all columns contain the same value) already exists in the table, the insert operation should be dismissed. This can be easily be done by defining unique keys and handle the upcoming error, but I cannot alter the table structure.
I'm sure that there is an easy way to catch this even in tables without unique keys. Of course I can manually check the presence of such a record using a SELECT
statement in advance, but there may be concurrent instances that modify my table in the meantime (between the check with SELECT
and the actual INSERT
).
I would like to perform the check and the INSERT
operation in one SQL command. Can anyone point me in the right direction?
Upvotes: 4
Views: 2388
Reputation: 6645
Let us assume that you have 5 columns in your table - col1, col2, col3, col4, col5. And assume that the data corresponding to these columns that you are trying to insert is in variables - $col1, $col2, $col3, $col4, $col5 (I'm assuming PHP as your language but please modify the variables format as per your nomenclature).
So your insert might look like:
INSERT INTO `tableA` (`col1`, `col2`, `col3`, `col4`, `col5`)
SELECT $col1, $col2, $col3, $col4, $col5
FROM `tableA`
WHERE NOT EXISTS (SELECT 1
FROM `tableA`
WHERE `col1` = $col1
AND `col2` = $col2
AND `col3` = $col3
AND `col4` = $col4
AND `col5` = $col5);
Another alternative might be:
INSERT INTO `tableA` (`col1`, `col2`, `col3`, `col4`, `col5`)
SELECT $col1, $col2, $col3, $col4, $col5
FROM `tableA`
WHERE `col1` = $col1
AND `col2` = $col2
AND `col3` = $col3
AND `col4` = $col4
AND `col5` = $col5
HAVING COUNT(1) = 0;
Hope this helps.
Upvotes: 5
Reputation: 26749
Without unique key the only way to ensure unique rows is not allowing any write-concurrency on the table (either with locking them or using the serialisable isolation level)
Upvotes: 0
Reputation: 3211
You can use table lock with the query and until your query has finished processing, no other process will modify it.
Check this link: http://www.mssqlcity.com/Articles/Adm/SQL70Locks.htm
and then do as you said " such a record using a SELECT statement in advance, but there may be concurrent instances that modify my table in the meantime (between the check with SELECT and the actual INSERT)."
Upvotes: 0