INSERT ON DUPLICATE KEY UPDATE a different value from the insert - mysql

I would like to do something like this (the updated value should be different than the inserted value):
"INSERT INTO notification_chat_counts (uid,group_id,count)
VALUES
(",$uid,",",$groupId,",1)
ON DUPLICATE KEY UPDATE
(count = count +1)"

Of course it is possible. Even the MySQL manual has example of inserting different value that the values which would got updated:
INSERT INTO table (a,b,c) VALUES (1,2,3) ON DUPLICATE KEY UPDATE c=c+1;
For your example, the correct query syntax would be:
$query = "INSERT INTO notification_chat_counts (uid,group_id,count)
VALUES (",$uid,",",$groupId,",1)
ON DUPLICATE KEY UPDATE count=count+1"
However for this statement to work you must have an UNIQUE type index defined for this table, so that MySQL can decide if such row already exists in the table or not.
Also remember that inserting values into SQL query like this is dangerous and not recommended. You should use prepared statements for that.

Related

how to avoid values() with multiple values? [duplicate]

This is my python code which prints the sql query.
def generate_insert_statement(column_names, values_format, table_name, items, insert_template=INSERT_TEMPLATE, ):
return insert_template.format(
column_names=",".join(column_names),
values=",".join(
map(
lambda x: generate_raw_values(values_format, x),
items
)
),
table_name=table_name,
updates_on=create_updates_on_columns(column_names)
)
query = generate_insert_statement(table_name=property['table_name'],
column_names=property['column_names'],
values_format=property['values_format'], items=batch)
print(query) #here
execute_commit(query)
When printing the Mysql query my Django project shows following error in the terminal:
'VALUES function' is deprecated and will be removed in a future release. Please use an alias (INSERT INTO ... VALUES (...) AS alias) and replace VALUES(col) in the ON DUPLICATE KEY UPDATE clause with alias.col instead
Mysql doumentation does not say much about it.What does this mean and how to can i rectify it.
INSERT_TEMPLATE = "INSERT INTO {table_name} ({column_names}) VALUES {values} ON DUPLICATE KEY UPDATE {updates_on};"
Basically, mysql is looking toward removing a longstanding non-standard use of the values function to clear the way for some future work where the SQL standard allows using a VALUES keyword for something very different, and because how the VALUES function works in subqueries or not in a ON DUPLICATE KEY UPDATE clause can be surprising.
You need to add an alias to the VALUES clause and then use that alias instead of the non-standard VALUES function in the ON DUPLICATE KEY UPDATE clause, e.g. change
INSERT INTO foo (bar, baz) VALUES (1,2)
ON DUPLICATE KEY UPDATE baz=VALUES(baz)
to
INSERT INTO foo (bar, baz) VALUES (1,2) AS new_foo
ON DUPLICATE KEY UPDATE baz=new_foo.baz
(This only works on mysql 8+, not on older versions or in any version of mariadb through at least 10.8.3)
Note that this is no different if you are updating multiple rows:
INSERT INTO foo (bar, baz) VALUES (1,2),(3,4),(5,6) AS new_foo
ON DUPLICATE KEY UPDATE baz=new_foo.baz
From https://dev.mysql.com/worklog/task/?id=13325:
According to the SQL standard, VALUES is a table value constructor that returns a table. In MySQL this is true for simple INSERT and REPLACE statements, but MySQL also uses VALUES to refer to values in INSERT ... ON DUPLICATE KEY UPDATE statements. E.g.:
INSERT INTO t(a,b) VALUES (1, 2) ON DUPLICATE KEY
UPDATE a = VALUES (b) + 1;
VALUES (b) refers to the value for b in the table value constructor for the INSERT, in this case 2.
To make the value available in simple arithmetic expressions, it is part of the parser rule for simple_expr. Unfortunately, this also means that VALUES can be used in this way in a lot of other statements, e.g.:
SELECT a FROM t WHERE a=VALUES(a);
In all such statements, VALUES returns NULL, so the above query would not have the intended effect. The only meaningful usage of VALUES as a function, rather than a table value constructor, is in INSERT ... ON DUPLICATE KEY UPDATE. Also, the non-standard use in INSERT ... ON DUPLICATE KEY UPDATE does not extend to subqueries. E.g.:
INSERT INTO t1 VALUES(1,2) ON DUPLICATE KEY
UPDATE a=(SELECT a FROM t2 WHERE b=VALUES(b));
This does not do what the user expects. VALUES(b) will return NULL, even if it is in an INSERT .. ON DUPLICATE KEY UPDATE statement.
The non-standard syntax also makes it harder (impossible?) to implement standard behavior of VALUES as specified in feature F641 "Row and table constructors".

Slick 3 is generating incorrect MySQL upsert statements for a single column table

I have a very simple MySQL table which represents a set of names using a single String column. I want to use Slick's insertOrUpdate but it is generating incorrect MySQL, causing errors. Specifically, it wants to execute
insert into `TABLE1_NAME` (`column`) values ('value') on duplicate key update
It doesn't specify what to update, so this fails. A similar table with two columns upserts fine, with statements like
insert into `TABLE2_NAME` (`key`, `other_col`) values ('value1', 'value2') on duplicate key update `other_col`=VALUES(`other_col`)
Has anyone seen this? We do set a primary key for TABLE1. We may be doing our table projection mapping incorrectly. We're using Slick 3.1.1.
class Table1(tag: Tag) extends Table[Table1Record](tag, "TABLE1_NAME") {
def value = column[String]("value", O.PrimaryKey, O.Length(254))
def * = (value) <> (Table1Record, Table1Record.unapply)
}
class Table2(tag: Tag) extends Table[Table2Record](tag, "TABLE2_NAME") {
def value1 = column[String]("value1", O.PrimaryKey, O.Length(254))
def value2 = column[String]("value2", O.Length(254))
def * = (value1, value2) <> (Table2Record.tupled, Table2Record.unapply)
}
There's no such concept of "insert or update" into a single column table. The single column is part of the key. If the key matches exactly, then are no other columns to update. If the key didn't match, then the newly inserted row won't be a duplicate of any key, so the update clause won't happen. Because there are no other columns to update, the generated SQL is malformed -- a bit of text has been generated with the assumption that some field names would be appended after it, but there were no field names to append.
By the way, for a table with two columns, the insert statement looks like
insert into `TABLE2_NAME` (`key`, `other_col`)
values ('value1', 'value2')
on duplicate key update `other_col`=VALUES(`other_col`)
It lists only the non-key columns in the update clause. (Getting this correct should help you to better understand what's going on with your single-column table.)

Insert to table or update if exists using MYSQL database

I have mysql database. I need to update country list on my table. there is some country in my table. I need to check that country if not exist and insert to the table. I'm used following sql script. But this is not working. when execute this code it will duplicate the record.
MySQL Query:
INSERT INTO `moneyexpressstore`.`countries` (`Name`, `Code`, `CurrencyId`) VALUES
('Australia', 'au', NULL) ON DUPLICATE KEY UPDATE Name=VALUES(Name)
thanks,
First make sure your database does not have duplicate records on column countries, then execute this
CREATE UNIQUE INDEX countriesindex ON countries (Name(50))
50 is the amount of characters that the index will search for "unique" values. For example if that number was 3, then these two different string would be considered the same, and a 1062 Duplicate Entry error would occur abcHELLO=abcWORLD and in your case it would force the UPDATE instead of INSERT.
If you get a 1062 error, that means you have duplicates in your db so find them remove them and try again.
After this your query will execute just fine and will update instead of duplicate on "Name"
Have a look in the documentation of mysql https://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
Try this:
insert into `moneyexpressstore`.`countries` (id, `Name`, `Code`, `CurrencyId`) values(NULL,'Australia', 'au', NULL) on duplicate key update name=values(name)
Please refer this link:
http://dev.mysql.com/doc/refman/5.1/en/insert-on-duplicate.html

Getting last insert id for mysql after Insert

I have a query like so:
INSERT INTO table1 (field1,field2) VALUES ('$value1','$value2') ON DUPLICATE KEY UPDATE field1 = '$value1'
I then want to get the last insert id if it does the insert, how can I do this? If the query ends up doing an update I dont want the last insert id. Is there a way to determine if it did an update or a insert?
I guess I should of searched the site before posting. Basically adding this worked:
id=LAST_INSERT_ID(id)
On the on duplicate update. I found that answer here:
Duplicate Key Last Insert ID
According to this MySQL Manual Page:
If a table contains an AUTO_INCREMENT
column and INSERT ... ON DUPLICATE KEY
UPDATE inserts or updates a row, the
LAST_INSERT_ID() function returns the
AUTO_INCREMENT value.

Does SQL Server Offer Anything Like MySQL's ON DUPLICATE KEY UPDATE

In MySQL, 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. For example, if column a is declared as UNIQUE and contains the value 1, the following two statements have identical effect:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE c=c+1;
UPDATE table SET c=c+1 WHERE a=1;
I don't believe I've come across anything of the like in T-SQL. Does SQL Server offer anything comparable to MySQL's ON DUPLICATE KEY UPDATE?
I was surprised that none of the answers on this page contained an example of an actual query, so here you go:
A more complex example of inserting data and then handling duplicate
MERGE
INTO MyBigDB.dbo.METER_DATA WITH (HOLDLOCK) AS target
USING (SELECT
77748 AS rtu_id
,'12B096876' AS meter_id
,56112 AS meter_reading
,'20150602 00:20:11' AS time_local) AS source
(rtu_id, meter_id, meter_reading, time_local)
ON (target.rtu_id = source.rtu_id
AND target.time_local = source.time_local)
WHEN MATCHED
THEN UPDATE
SET meter_id = '12B096876'
,meter_reading = 56112
WHEN NOT MATCHED
THEN INSERT (rtu_id, meter_id, meter_reading, time_local)
VALUES (77748, '12B096876', 56112, '20150602 00:20:11');
There's no DUPLICATE KEY UPDATE equivalent, but MERGE and WHEN MATCHED might work for you
Inserting, Updating, and Deleting Data by Using MERGE
You can try the other way around. It does the same thing more or less.
UPDATE tablename
SET field1 = 'Test1',
field2 = 'Test2'
WHERE id = 1
IF ##ROWCOUNT = 0
INSERT INTO tablename
(id,
field1,
field2)
VALUES (1,
'Test1',
'Test2')
SQL Server 2008 has this feature, as part of TSQL.
See documentation on MERGE statement here - http://msdn.microsoft.com/en-us/library/bb510625.aspx
SQL server 2000 onwards has a concept of instead of triggers, which can accomplish the wanted functionality - although there will be a nasty trigger hiding behind the scenes.
Check the section "Insert or update?"
http://msdn.microsoft.com/en-us/library/aa224818(SQL.80).aspx