mysql strange "duplicate entry" error - mysql

I have a problem I don't quite understand. I parse some feeds with Ruby and save their contents in a database. I created a "hash"-column which is the md5-hash of every post url. That column is UNIQUE because I don't want to post anything twice.
It works fine actually:
Mysql::Error: Duplicate entry '28edb7c2b3cd074d226fc4ae37baedd7' for key 'hash'
But the script stops at this point. I don't get that, I know for a fact that using INSERT with PHP always worked like a charm, so if there was duplicate entry it ignored it and went on.
Can anybody help me? Would "INSERT IGNORE" create a double entry or would it just ignore the error message and go on?

Sounds like your Ruby script needs some exception handling.

You can rewrite your query so that instead of INSERT INTO it uses
REPLACE INTO ...
or
INSERT INTO ... ON DUPLICATE KEY UPDATE
This way attempting to insert a duplicate key will update the existing record instead of erroring out.
See here and here for more information.
Update:
INSERT IGNORE not touch your existing data if it encounters a duplicate key. The documentation says:
You can use REPLACE instead of INSERT
to overwrite old rows. REPLACE is the
counterpart to INSERT IGNORE in the
treatment of new rows that contain
unique key values that duplicate old
rows: The new rows are used to replace
the old rows rather than being
discarded.
If you use the IGNORE keyword, errors
that occur while executing the INSERT
statement are treated as warnings
instead. 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 still is not inserted,
but no error is issued.

In PHP, if MySQL returns an error, it doesn't normally kill the PHP script. It sounds to me as though that's not the case in Ruby. Either catch the exception and process it or use INSERT IGNORE, in which case MySQL returns a warning instead of an error (unless it was told not to).

"INSERT IGNORE" Should Prevent Ruby from exiting and shouldn't effect your data. However if you want to know when this is happening you have to put in some error handling.
begin
DATABASE.query(insertHash)
rescue
puts "Error: " + $!.to_s + "Backtrace >>: " + $#.to_s
end
Should show the error with out exiting the ruby script.
Or you could use this to indicate to the user that there is already an entry
Hope this helps

Related

MySQL UPDATE statement is throwing "Column count doesn't match value count" error

(NOTE: I know this is an error that's commonly asked about, but most of the time, the issue is in an INSERT statement. I couldn't find a question on this website where this error happened during an UPDATE.)
I have a table in MySQL (InnoDB / v. 5.7.19) called RESULTS which has, among others, two columns called TYPE and STATUS. Both are of type ENUM, with PASS, FAIL and IGNORE being the supported values in both. I'm trying to run this UPDATE statement on that table, using Workbench (also tried the same directly on the DB machine, using the mysql command):
update `RESULTS` set `TYPE`='IGNORE' where `STATUS`='IGNORE';
I'm getting this error:
Error Code: 1136. Column count doesn't match value count at row 1
Changing the single quotes to double quotes didn't help. I'm able to run this query successfully:
select count(`TYPE`) from `RESULTS` where `STATUS`='IGNORE';
I'm probably making a silly mistake here, but can anyone point out what's wrong with the UPDATE statement?
As requested I am posting it as an answer.
The error basically is self-explanatory like performing an operation on set of attributes but the values provided in the query are not enough. But in your case, you are performing an update operation with all attributes and their values and still, this error appears it may be a case that there is some trigger is registered for this table probably on before/after the event, If that is the case you need to update or remove that trigger if no needed.

Multiple insert in mysql table, some of which may be repeated

I'm developing a php script in which I insert multiple data into a mysql table, but some of this data may already be inserted. I can try to insert each of the individual data and detect the #1062 error (duplicate entry), but it would be very inefficient since it can be more than 100 entries. So, is there any way to do this in one query or must I use a query for each entry to be inserted?
Thanks a lot.
You'll want to use the INSERT ... ON DUPLICATE KEY UPDATE command to accomplish this. In the "ON DUPLICATE KEY UPDATE" section, you can just do some kind of update that changes nothing. For example, "SET fieldName=fieldName", just so nothing is actually changed.
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html

MySQL stored procedure, do not ever raise error?

I would like to make a Stored procedure in MySQL with an try/catch to prevent the error going to my java project. But since there is no try/catch in MySQL im searching for alternatives.
The only thing i need to prevent, is to dont get a "Duplicate key" error from mysql in my java project. If i get this error, i dont want to show anything and act like it has inserted normal.
Is this possible?
Why don't you catch this error withi your application?
Anyway, from docs: http://dev.mysql.com/doc/refman/5.5/en/insert.html
If you use the IGNORE keyword, errors that occur while executing the
INSERT statement are treated as warnings instead. 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 still is not inserted, but no error is
issued
.

Is inserting a new database entry faster than checking if the entry exists first?

I was once told that it is faster to just run an insert and let the insert fail than to check if a database entry exists and then inserting if it is missing.
I was also told that that most databases are heavily optimized for reading reading rather than writing, so wouldn't a quick check be faster than a slow insert?
Is this a question of the expected number of collisions? (IE it's faster to insert only if there is a low chance of the entry already existing.) Does it depend on the database type I am running? And for that matter, is it bad practice to have a method that is going to be constantly adding insert errors to my error log?
Thanks.
If the insert is going to fail because of an index violation, it will be at most marginally slower than a check that the record exists. (Both require checking whether the index contains the value.) If the insert is going to succeed, then issuing two queries is significantly slower than issuing one.
You can use INSERT IGNORE so that if the key already exist, the insert command would just be ignored, else the new row will be inserted. This way you need to issue a single query, which checks the duplicate values as well inserts new values too.
still Be careful with INSERT IGNORE as it turns EVERY error into a warning. Read this post for insert ignore
On duplicate key ignore?
I think INSERT IGNORE INTO .... can be used here, either it will insert or ignore it.
If you use the IGNORE keyword, errors that occur while executing the INSERT statement are treated as warnings instead. 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 still is not inserted, but no error is issued.
If you want to delete the old value and insert a new value you can use REPLACE You can use REPLACE instead of INSERT to overwrite old rows.
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.
Else use the INSERT IGNORE as it will either inserts or ignores.
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 still is not inserted, but no error is issued.
If your intension is to Insert if its a new record OR Update the record if it already exists then how about doing an UPSERT?
Check out - http://vadivel.blogspot.com/2011/09/upsert-insert-and-update-in-sql-server.html
Instead of checking whether the record exists or not we can try to Update it directly. If there is no matching record then ##RowCount would be 0. Based on that we can Insert it as a new record. [In SQL Server 2008 you can use MERGE concept for this]
EDIT: Please note, I know this works for MS SQL Server and I don't know about MySQL or ORACLE

Insertion without duplication in MySQL

I'm fetching data from a text file or log periodically and it gets inserted in the database every time fetched. Is there a way in MySQL that the insert is only done when the log files are updated or I have to do it using the programming language ? I mean Is there a type of insert that when It sees a duplicate primary key, It doesn't give an error of "Duplicate Entry" .. It just ignore.
Put the fetch in a logrotate postrotate script, and fetch from the just rotated log.
Ignoring duplicates can be done with either INSERT IGNORE OR INSERT .... ON DUPLICATE KEY UPDATE syntax (which will either ignore the lines causing a duplcate unique key, or give you the possibility to alter some values in the existing row.)