I am using the node.js mysql package where I can create a connection and after connection.query(..) .., close the connection.
I have a collection of rows that I want to update in mysql database, and I don't know if the rows exist or not. Here I have two solutions but I don't know which one is better:
delete all the rows I want to update in mysql database and insert all rows using one connection.query(..)..
sudo code: 1. delete from table where id = ..[],
2. insert into table set ...
check each row that I want to update/insert, if the id exists in mysql database, then send query to update, otherwise insert.
sudo code: 1. for each row in list
2. check if the row exists in mysql
3. if exists, then send query to update;
if not exists, then send query to insert
for the second solution, I concerned that might be too time-consuming. Any one have some suggestions? What is the best way to do this?
I'm new to these stuff so I don't know if it is better to send multiple queries inside a for loop, especially in node each connection.query is a function with callback. Which one will have better overall performance?, or any other solutions?
Use insert ... on duplicate key update
Example:
insert into `tableName` (col1, col2, col3) values ( 'v1', 'v2', 'v3') on dupicate key update `col3`='v3'
*This wouldn't work if the key in this case is an auto_increment counter.
Source: http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html
Related
This question already has answers here:
How can I do 'insert if not exists' in MySQL?
(11 answers)
Closed 1 year ago.
I found a not so nice method for checking if there a row already exists, and if it does exists, then it doesn't add it to avoid duplicates. Am i completely crazy to rely on this method or should i go old fashioned way where i check if it exists BEFORE trying to insert row in database?
The table is VERY simple :)
-ID [PK]
-Message
-Hashed_message [UNIQUE] (stored procedure, takes message and hashes it upon insert)
Now when i try to insert a new row i would say
*`insert into .... message = xxx
Upon insertion mysql will create a hash on message automatically, but since it's an unique column, incase the hash already exists in database, it will simply throw an error, and no duplicates will exist ever... i hope.
The reason for using hashes, is simply to avoid checking duplicates by scanning every large message, instead i though a short hash would be easier to check for duplicates.
So is this method bad for avoiding duplicates?
I mean i could before insert, manually create that hash of my message and check if that hash exists and THEN insert the message, but i would hope to avoid always trying to match the stored procedure function on PHP as well.
quick note: there is a similar thread about insert and then ignoring error on duplicate, but this one is related to how it is handled when a derived column(Stored procedure) is used to accomplish this
If the hashed message has to be unique, create a key on that column with the UNIQUE constrain: so there won't be two rows with the same hash.
Then, when you insert a new row modify your query with the following:
INSERT INTO table SET message='$message', hashed_message='$hashed_message'
ON DUPLICATE KEY id=id;
This will perform an insert if the hashed_message is unique. Otherwise will not do any update.
If you want to update something in case of duplicate your query will become:
INSERT INTO table SET message='$message', hashed_message='$hashed_message'
ON DUPLICATE KEY UPDATE message='$updated_message'
just to make an example.
Note that this method won't raise any exception in case of duplicate values: you need extra logic if you need to perform actions in your frontend in case of duplicates (i.e. message shown to the user).
More details here
Ok, I have an update function with a weird twist. Due to the nature of the structure, I run a delete query then insert query, rather than an actual "Update" query. They are specifically run in that order so that the new items inserted are not deleted. Essentially, items are deleted by an attribute id that matches in the insert query. Since the attribute is not a primary index, "ON DUPLICATE KEY UPDATE" is not working.
So here's the dilemma. During development and testing, The delete query will run without fail, but if I'm screwing around with the input for the INSERT query and it fails, then the DATA has been deleted without being reinserted, which means regenerating new test data, and even worse, if it fails in production, then the user will lose everything they were working on.
So, I know MySQL validates a query before it is actually run, so is it possible to make sure the INSERT query validates before running the DELETE query?
<cfquery name="delete" datasource="DSOURCE">
DELETE FROM table
WHERE colorid = 12
</cfquery>
<!--- check this query first before running delete --->
<cfquery name="insert" datasource="DSOURCE">
INSERT INTO table (Name, ColorID)
VALUES ("tom", 12)
</cfquery>
You have 2 problems.
Since the attribute is not a primary index, "ON DUPLICATE KEY UPDATE"
is not working.
Attribute doesn't have to be PRIMARY KEY. It's sufficient if it's defined as UNIQUE KEY, which you can do without penalties.
And number two: if you want to execute a series of queries in sequence, with ALL of them being successful and none failing - the term is transaction. Either all succeed or nothing happens. Google about MySQL transactions to get better overview of how to use them.
Since you use WHERE colorid = 12 as your delete criterium, colorid must be a unique key. This gives you two ways of approachng this with a single query
UPDTAE table SET NAME="tom"
WHERE colorid=12
OR
REPLACE INTO table (Name, ColorID)
VALUES ("tom", 12)
MySQL: In update trigger's body, can I obtain the value of a column that is specified in the where clause of the triggering query if the where clause does not match any rows at all?
I have to do the following, but NOT USING direct query such as ON DUPLICATE KEY UPDATE so on:
If I have:
UPDATE my_table SET idiotism_level=5 WHERE name='Pencho'
... and the where clause match NO ROWS, I'd want to automatically trigger an insertion of a row having name='Pencho' before the update, and then the UPDATE would presumably match, and work properly.
Is it possible ?
This could be make in a RULE in other database systems (PostgreSQL), that does not exists in MySQL. It's a Rule and not a trigger as you should analyse the query and not the result of the query.
But for MySQL you can make pre-query jobs by using MySQL-Proxy. You should be able to alter your update query and build an insert, By running some 'check row exists' extra query from the MySQL-Proxy (I'm not saying this is a nice solution, but if you have no way to make the code to act better you can fix it at this level).
No. An update trigger fires once for each row that gets updated, not once for each update command that's executed. There's no way to make the trigger fire if nothing is updated. You would need to handle this in your application by checking the number of updated rows returned by your query.
If name has a unique index on it you can use REPLACE
REPLACE INTO my_table (idiotism,name) VALUES ( 5,'Pencho');
I need to add a row to a MySQL database table but only if the row doesn't already exist. My database server just went down so I can't test this, but will this work as expected?
INSERT INTO `blocks` (`block_file`,`settings_group`)
VALUES ('announcements','announcement_settings')
WHERE NOT EXISTS (SELECT `block_file`,`settings_group`
FROM `blocks`
WHERE `block_file`='announcements' AND `settings_group`='announcement_settings')
It seems like sound logic. Is this a valid query or is there a better way of doing this?
Just create UNIQUE index on (block_file,settings_group) columns, and MySQL will never let you insert a row that would duplicate these values.
And to answer the question: No, it will not work at all.
I'm trying to create a code for a single button where it will perform either of two actions where it will add to the database if the user currently don't have the record while it will update the user's record if the user has records already. I've done it like this:
if() {
mysql_query("INSERT INTO table...");
}
else {
mysql_query("UPDATE table SET...");
}
Is it possible?
Yes, what you've written will work. If you have a way to know if there already exists a row or not without making an additional query just for this bit of code, then do exactly as you wrote.
If, however, you planned to first SELECT from the table to see if a row exists, then conditionally INSERT or UPDATE, you will perform more queries than necessary.
It would be better to either:
Have a PRIMARY KEY or other constraint on the table prevent duplicate INSERTs. Then issue an INSERT ... ON DUPLICATE KEY UPDATE query. This will attempt to INSERT the row, and if it is a duplicate, automatically perform the specified UPDATE to that row instead.
Issue the UPDATE query and check mysql_affected_rows to see if it updated an existing row. If not, then issue the INSERT query to create the new row.
Which one is more appropriate depends on your application.
you can use INSERT ... ON DUPLICATE KEY UPDATE Syntax like:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
If you have properly set unique keys, you should use REPLACE so you could remove the if.
REPLACE INTO table VALUE (...);
Pay attention that this is a MySQL extension, thus not portable to other DBs.
Yes, you could try the insert then if it fails try the update.
But you could use the MYSQL sql "REPLACE" keyword, which will insert a new record if it doesn't exist or delete the existing record and insert your new one if it does.
You could also use the INSERT ... ON DUPLICATE KEY UPDATE syntax
(explained here - Link to MYSQL ref which seems to be the closest fit to your requirement.
yes it is possible
first write a query for check that record is already exist or not.
Yes it is possible , it will work