Should I handle ER_DUP_ENTRY before or after INSERT? - mysql

I have Node.js backend application running with MySQL.
I am handling ER_DUP_ENTRY on Node.js side, after INSERT query executed on current version of server. So I am running INSERT and then if MySQL returns that ER_DUP_ENTRY, I show up a warning to the user.
I thought getting this error every time from MySQL put an extra load on the database.
My question is, should I have to check database with SELECT for DUPLICATE entry and then execute INSERT query or is there no problem with the current version?

You don't want to check before executing the insert query. Just set it up UNIQUE constraint over the table for a specific column or combined column(multiple). So whenever you will insert the same data again MySQL will handle this duplicacy.
check the insert query response status. Then you can determine this is success / failed(duplicate or some other error).

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.

How can Mysql INSERT operations be optimized for possible duplicate entries?

In my NodeJs application, I am using a threads(defined by my self) to open ports in a computer. There is a restriction that only one thread should be bound to each port.
I am maintaining a table(PORTS) in Mysql which holds data about open ports and the bound thread. Currently I am using the following approach to avoid two threads being bind to the same port.
=> Insert an entry to the PORTS table with port number as the PRIMARY KEY. This will throws the following error
error inserting semaphore port:10014 error Error: ER_DUP_ENTRY: Duplicate entry 'port:10014' for key 'NAME'
I capture this error and then try another port until an error is not thrown.
Is this a good practice? Or should I first check if the value exists using a SELECT query and then INSERT entry if not?
Note- AFAIK In the second approach, SELECT and INSERT can be run as an atomic operation by using an SQL Transaction.
Assuming you have multiple 'clients' attempting to get 'ports' at the same time, your second approach is bad. This is because a different client could sneak in between the SELECT and INSERT and grab the port.
Your first approach is better because it is 'atomic'. And it is a single action, thereby being faster (not that speed is a big deal).

Why am I getting a table doesn't exist error for a table that exists?

I am running a simple update statement:
UPDATE sometab
SET `somefield1` = '19',
`somefield2` = '3734941'
WHERE somefield3 = '1234';
and I am getting the error:
ERROR 1146 (42S02): Table 'prod._sometab_new' doesn't exist
I can successfully select from the table where somefield3 is 1234.
Why am I getting a table doesn't exist error for a table that exists? And why does the error message refer to a different table? I don't see any triggers associated with the table.
Additional information: A colleague just noticed that it is referring to a prod scheme, but the statement is running in a dev schema built from prod. The update statement works in DBs that were built a few days ago using the same method, but all of the DBs built after some, as of yet, unknown time exhibit the error.
The current theory is that a conversion script to move us to UTF-8 is currently running and creating tables like _ORIG_new as part of its conversion. We are going to wait for the conversion script to finish and then rebuild the dev databases and see if the error still persists.
Does this happen if you also try Insert into or Delete statements ?
Insert INTO sometab(somefield1, somefield2) VALUES (a, b).
If that works you should not have problems probably, otherwise you have problems accessing your database.
Second, are you sure you are using the correct database file and that are you connected to it properly. If you are using it in external application (c#), check your connection strings.
Also check how are you executing the query. I cant think of other more specific solution to your problem

INSERT IGNORE and ON DUPLICATE KEY UPDATE not working in SQL Server 2008 R2

I'm trying to import some data from a MS-Access file to my SQL Server database. I keep getting primary key errors because some of the data overlaps. Therefore I tried using ON DUPLICATE KEY UPDATE as well as INSERT IGNORE. Both seem to be unknown to my SQL Server (running 2008 R2) as I get syntax errors. Do I need some add-on library or is INSERT IGNORE and ON DUPLICATE KEY not usable when inserting with a select query to .mdb? Here's the code snippet:
INSERT INTO XCManager.XC_DATA1 (STATION_ID, SENSORNAME, TIME_TAG, ORIG_VALUE, ED_VALUE, SOURCE)
SELECT STATION_ID, SENSORNAME, TIME_TAG, ORIG_VALUE, ED_VALUE, SOURCE
FROM OPENDATASOURCE ('Microsoft.Jet.OLEDB.4.0',
'Data Source=H:\OPERATIONS & MAINTENANCE SECTION\Modeling & Gauging\PCBase2\PCBASE2 Files.mdb')...RUMN3
ON DUPLICATE KEY UPDATE STATION_ID=STATION_ID
Here's the parsing result:
Msg 156, Level 15, State 1, Line 3
Incorrect syntax near the keyword 'ON'.
SQL Server does not support INSERT IGNORE or ON DUPLICATE. That syntax is specific to MySQL.
If you had looked up the INSERT statement in the SQL Server manual you would have seen that.
You need to use the MERGE statement in order to update or insert.
when inserting with a select query to .mdb
I don't understand that part. If you have SQL Server you are not "inserting into a .mdb".
Are you maybe running MS Access instead? In that case the MERGE will not work either as far as I know (you would need to check the manual for MS Access for an equivalent statement)
not sure if this got resolved, but one way to accomplish "insert ignore" in sql server is to check the "ignore duplicates" box when creating a unique index on a set of columns for a table. When you do this, SQLServer will not throw an exception, just a warning, so if you bulk insert with an index like this, then it will ignore the dupes for you.
The trouble with this is, if you have a TON of rows (10s of millions or more) having an index on the table as you bulk insert will be slower.

Is there any alternative to "last_update_ID()" for mySQL?

I am currently working on a big web project using ASP and MySQL.
When inserting into multiple tables I've been using last_update_ID(), but after some research I've found that that SQL statement isn't safe.
So. the problem:
I use two different computers, with different internet connections.
Both computers are logged onto the system I am currently building. I have made a page that prints the connection_id(), and last_update_id.
If I update any table with one of the computers the other one also gets that last_update_ID.
Both computers have the same connection_ID.
What can I do to get around this?
I don't want to (if it's not necessary) do a select statement after the first INSERT; to search for the row that I inserted, to get the correct ID of that row.
It's not my server I am using so I can't make any large changes of the database.
I guess that this problem occurs because the webpages use the same loginName & password to connect to the database, is that true?
Is there any other alternative to get the last update ID? that is totally safe..
I close every connection at the end of the asp page. but that doesn't change the connection_ID.
The connection ID is the for a few minutes even thou I open up different web pages on the server.
I believe the LAST_INSERT_ID() is correct for the current session. So each session receives it's own correct value. Either I don't understand your question or you think you have a problem but you don't.
I am not aware of any LAST_UPDATE_ID() function, on an update you can easily retrieve the updated rows by SELECTing them with the same WHERE clause (before the update)?
reference: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
For LAST_INSERT_ID(), the most
recently generated ID is maintained in
the server on a per-connection basis.
It is not changed by another client.
It is not even changed if you update
another AUTO_INCREMENT column with a
nonmagic value (that is, a value that
is not NULL and not 0). Using
LAST_INSERT_ID() and AUTO_INCREMENT
columns simultaneously from multiple
clients is perfectly valid. Each
client will receive the last inserted
ID for the last statement that
client executed.
If you want to retrieve the LAST_INSERT_ID from an INSERT query with an ON DUPLICATE KEY UPDATE clause, you can also use the LAST_INSERT_ID() function to retrieve the value of the AUTO_INCREMENT column that was updated:
reference: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
If a table contains an AUTO_INCREMENT
column and INSERT ... UPDATE inserts a
row, the LAST_INSERT_ID() function
returns the AUTO_INCREMENT value. If
the statement updates a row instead,
LAST_INSERT_ID() is not meaningful.
However, you can work around this by
using LAST_INSERT_ID(expr). Suppose
that id is the AUTO_INCREMENT column.
To make LAST_INSERT_ID() meaningful
for updates, insert rows as follows:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
Your server appears to have connection pooling turned on. What this means is that the database connection is held open after a script finishes, and the next script that comes along uses it, and thus can see any variables that were set on that connection, including LAST_INSERT_ID().
What can't happen is two script instances sharing a connection at the same time. Thus, if your server is busy enough to need to run two script instances at exactly the same time, it will simply create a second database connection, with its own separate LAST_INSERT_ID() variable, and won't interfere with the first.
In short, as long as the INSERT and the LAST_INSER_ID() request happen within the same script (and you don't somehow close the database connection between them), they're completely safe, as your script has exclusive use of that connection.