As per a prior question, I created a Unique Index on a name field. I've simplified my import so I don't need to merge fields any longer, just import from SourceTable into DestinationTable, the latter having Unique Index on Name.
I got an error immediately about a duplicate value existing when I tried to do the insert, so I guess that is good news, is there a way to specify an insert that will just skip the duplicate values and go to the next vs throwing out the "[Err] 1062 - Duplicate entry 'Actor' for key 2" and quitting?
In MySQL you can use insert ignore to ignore all errors, including duplicate key.
To just ignore this one error, you can use on duplicate key update:
insert into t(cols)
select values
from wherever
on duplicate key update col1 = values(col1);
The update part doesn't do anything important. It just does something so no error is reported.
Related
I have a simpe query like so:
INSERT INTO myTable (col1, col2) VALUES
(1,2),
(1,3),
(2,2)
I need to do a check that no duplicate values have been added BUT the check needs to happen across both column: if a value exists in col1 AND col2 then I don't want to insert. If the value exists only in one of those columns but not both then then insert should go through..
In other words let's say we have the following table:
+-------------------------+
|____col1____|___col2_____|
| 1 | 2 |
| 1 | 3 |
|______2_____|_____2______|
Inserting values like (2,3) and (1,1) would be allowed, but (1,3) would not be allowed.
Is it possible to do a WHERE NOT EXISTS check a single time? I may need to insert 1000 values at one time and I'm not sure whether doing a WHERE check on every single insert row would be efficient.
EDIT:
To add to the question - if there's a duplicate value across both columns, I'd like the query to ignore this specific row and continue onto inserting other values rather than throwing an error.
What you might want to use is either a primary key or a unique index across those columns. Afterwards, you can use either replace into or just insert ignore:
create table myTable
(
a int,
b int,
primary key (a,b)
);
-- Variant 1
replace into myTable(a,b) values (1, 2);
-- Variant 2
insert ignore into myTable(a,b) values (1,2);
See Insert Ignore and Replace Into
Using the latter variant has the advantage that you don't change any record if it already exists (thus no need to rebuild any index) and would best match your needs regarding your question.
If, however, there are other columns that need to be updated when inserting a record violating a unique constraint, you can either use replace into or insert into ... on duplicate key update.
Replace into will perform a real deletion prior to inserting a new record, whereas insert into ... on duplicate key update will perform an update instead. Although one might think that the result will be same, so why is there a statement for both operations, the answer can be found in the side-effects:
Replace into will delete the old record before inserting the new one. This causes the index to be updated twice, delete and insert triggers get executed (if defined) and, most important, if you have a foreign key constraint (with on delete restrict or on delete cascade) defined, your constraint will behave exactly the same way as if you deleted the record manually and inserted the new version later on. This means: Either your operation fails because the restriction is in place or the delete operation gets cascaded to the target table (i.e. deleting related records there, although you just changed some column data).
On the other hand, when using on duplicate key update, update triggers will get fired, the indexes on changed columns will be rewritten once and, if a foreign key is defined on update cascade for one of the columns being changed, this operation is performed as well.
To answer your question in the comments, as stated in the manual:
If you use the IGNORE modifier, errors that occur while executing the INSERT statement are ignored. For example, without IGNORE, a row that duplicates an existing UNIQUE index or PRIMARY KEY value in the table causes a duplicate-key error and the statement is aborted. With IGNORE, the row is discarded and no error occurs. Ignored errors may generate warnings instead, although duplicate-key errors do not.
So, all violations are treated as warnings rather than errors, causing the insert to complete. Otherwise, the insert would be applied partially (except when using transactions). Violations of duplicate key, however, do not even produce such a warning. Nonetheless, all records violating any constraint won't get inserted at all, but ignore will ensure all valid records get inserted (given that there is no system failure or out-of-memory condition).
I have table MySQL with Primary Key Composed of 2 fields, as below
Already existing records in the table are:
The INSERT query I am issuing is:
When I run the query:
INSERT INTO `case_data`
VALUES ('WCD/2016/1000017', 2, '2016-09-29', 'WCD',***********************
The error message displayed is:
[Err] 1062 - Duplicate entry 'WCD/2016/1000017' for key 'PRIMARY'
Am I violating the Primary Key constraint?
Thanks in advance.
You could check if the primary key values of a row you are trying to insert already exist in a table:
SELECT COUNT(*)
FROM case_data
WHERE caseno = 'WCD/2016/1000017' AND iteration = 2;
If it returns 0 then you will not violate the PK constraint and are safe to insert the row you wish (assuming there are no additional checks, triggers, constraints). Otherwise it will return 1 which means that you already have a row with values in those columns, thus you would violate uniqueness of the row which is not allowed.
When it returns 0 just issue an INSERT command. Also, remember to specify your column tables within the statement to make sure every value from your VALUES is being put within the right column of your destination table:
INSERT INTO case_data (caseno, iteration, casedate, casetype)
VALUES ('WCD/2016/1000017', 2, '2016-09-29', 'WCD');
Avoid using backticks around your column and table names if they don't contain alternative characters like commas or spaces. This will make your code more readable and definitely speed up your writing time.
I am using a API to fetch records from a different server and insert into my local database but when a particular field say apiserverID is duplicate i just want to update fields.
my problem is that i have table structure as
myPrimaryKey
apiserverID
....
.....
.....
updateDate
now i want simple procedure to update the row if apiserverID is duplicate.
Only solution i know is i have to check (SELECT) if the key apiserverID exist then update else insert.
but i don't want do programming for this is this possible in one query
EDIT : Main problem is that INSERT ... ON DUPLICATE KEY UPDATE don't work for a particular field, it include all the keys to check duplicity
if there is a single multiple-column unique index on the table, then the update uses (seems to use) all columns (of the unique index) in the update query.
So if there is a UNIQUE(a,b) constraint on the table in the example, then the INSERT is equivalent to this UPDATE statement:
UPDATE table SET c=c+1 WHERE a=1 AND b=2;
(and not "a=1 OR b=2")
But in your case it will work as expected because first one is your primary key and it will never be duplicate form the server so only thing which can be duplicate is your apiserverID so when ever found duplicate it will update the row else always a new insert will be executed
I have an insert query for MySQL that looks like this:
INSERT INTO table (foo, bar, fooo, baar, etc) VALUES (?,?,?,?,?)
It is used in a script to migrate some columns and keeps encountering duplicate primary keys. (Old database was awful and poorly maintained).
Is there a way I can just tell it to replace the whole offending row with the current values tossing out the old stuff entirely? I know there is an ON DUPLICATE KEY UPDATE command, but I don't know if it would help me as all I've seen it used for is incrementing.
ANSWER: INSERT INTO table (foo, bar, fooo, baar, etc) VALUES (?,?,?,?,?) ON DUPLICATE KEY UPDATE foo=?, bar=?, fooo=?, baar=?, etc=?
Keep in mind that you have to add the values in the referenced array again to account for the extra question marks.
on duplicate key update should work, as should a replace statement.
From MySQL manual:
If you specify ON DUPLICATE KEY
UPDATE, and a row is inserted that
would cause a duplicate value in a
UNIQUE index or PRIMARY KEY, an UPDATE
of the old row is performed.
What you said:
Is there a way I can just tell it to
replace the whole offending row with
the current values tossing out the old
stuff entirely?
Conclusion: why don't you just try it? It seems it does exactly what you want.
Edit: Since you haven't provided any examples of what you were trying to do, I'll use some from MySQL's website.
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Or if you want something that relates more to real world:
INSERT INTO table(int_field, str_field, float_field) VALUES (15, 'some string', '1.22')
ON DUPLICATE KEY UPDATE int_field = 15, str_field = 'some_string', float_field = '1.22';
Kinda strange to put it into words that short, heh.
Anyway, what I want is basically to update an entry in a table if it does exist, otherwise to create a new one filling it with the same data.
I know that's easy, but I'm relatively new to MySQL in terms of how much I've used it :P
A lot of developers still execute a query to check if a field is present in a table and then execute an insert or update query according to the result of the first query.
Try using the ON DUPLICATE KEY syntax, this is a lot faster and better then executing 2 queries. More info can be found here
INSERT INTO table (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=9;
if you want to keep the same value for c you can do an update with the same value
INSERT INTO table (a,b,c) VALUES (4,5,6)
ON DUPLICATE KEY UPDATE c=6;
the difference between 'replace' and 'on duplicate key':
replace: inserts, or deletes and inserts
on duplicate key: inserts or updates
if your table doesn't have a primary key or unique key, the replace doesn't make any sense.
You can also use the VALUES function to avoid having to specify the actual values twice. E.g. instead of
INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=6;
you can use
INSERT INTO table (a,b,c) VALUES (4,5,6) ON DUPLICATE KEY UPDATE c=VALUES(c);
Where VALUES(c) will evaluate to the value specified prevously (6).
Use 'REPLACE INTO':
REPLACE INTO table SET id = 42, foo = 'bar';
See more in the MySQL documentation
As the others have said, REPLACE is the way to go. Just be careful using it though, since it actually does a DELETE and INSERT on the table. This is fine most of the time, but if you have foreign keys with constraints like ON DELETE CASCADE, it can cause some big problems.
Look up REPLACE in the MySQL manual.
REPLACE works exactly like INSERT,
except that if an old row in the table
has the same value as a new row for a
PRIMARY KEY or a UNIQUE index, the old
row is deleted before the new row is
inserted. See Section 12.2.5, “INSERT
Syntax”.
REPLACE is a MySQL extension to the
SQL standard. It either inserts, or
deletes and inserts. For another MySQL
extension to standard SQL — that
either inserts or updates — see
Section 12.2.5.3, “INSERT ... ON
DUPLICATE KEY UPDATE Syntax”.
If you have the following INSERT query:
INSERT INTO table (id, field1, field2) VALUES (1, 23, 24)
This is the REPLACE query you should run:
REPLACE INTO table (id, field1, field2) VALUES (1, 23, 24)