If row dont exist, insert instead of update - mysql

UPDATE userpostratings SET rating = $rating WHERE postID = 8
If a there isnt a row in userpostratings with postID = 8 i wanna INSERT instead. Could this be done with sql or should I do it in php
Thanks
Tomek

see here: How do I update if exists, insert if not (AKA "upsert" or "merge") in MySQL?

If you have a UNIQUE index on postID, then you can do something like:
INSERT INTO userpostratings (rating, postID) VALUES ($rating, 8)
ON DUPLICATE KEY UPDATE rating = $rating;

here you go
http://nl2.php.net/manual/en/function.mysql-affected-rows.php
> mysql_query("UPDATE mytable SET used=1
> WHERE id < 10"); printf ("Updated
> records: %d\n",
> mysql_affected_rows());

Related

ON DUPLICATE KEY UPDATE only if second condition true

How do i update only if a second condition is true, it seems my version of mysql doesnt allow a WHERE at the end of ON DUPLICATE syntax.
INSERT INTO `proxies` (`proxy`,`response`,`PAYMENT`,`type`,`country`,`status`,`tier`,`last_checked`,`last_active`,`response_time`)
VALUES ('111.9.204.96:8123','200','coolproxies','anon','China','active','3','1400624136','1400624136','1.577639')
ON DUPLICATE KEY UPDATE `response`='200',`response_time`='1.577639',`type`='anon',`country`='China',`status`='active',`tier`='2',`last_checked`='1400624137'
this works ok, but I need to only update when WHERE last_checked < '1400624137' is true.
This is what the query that does this looks like.
INSERT INTO `proxies` (`proxy`,`response`,`PAYMENT`,`type`,`country`,`status`,`tier`,`last_checked`,`last_active`,`response_time`)
VALUES ('207.204.249.193:21320','200','scanner','anon','United States','active','1','1400633866','1400633866','1.59696')
ON DUPLICATE KEY UPDATE
`response_time` = IF(`last_checked` < '1400633866', '1.59696', `response_time`),
`status` = IF(`last_checked` < '1400633866', 'active', `status`),
`last_checked` = IF(`last_checked` < '1400633866', '1400633866', `last_checked`),
`last_active` = IF(`last_checked` < '1400633866', '1400633866', `last_active`);
An alternative to doing it in 2 queries as #GordonLinoff mentioned, is to use the method described in this related question you can use an IF to update based on a condition.
INSERT INTO `proxies` (...)
VALUES (...)
ON DUPLICATE KEY UPDATE
my_column = IF(last_checked < '1400624137', VALUES(my_column), my_column)
Basically what the IF does is when TRUE then update the field to the new value, otherwise if FALSE set it to the current value, which means no change to your existing data.
I think you need to do this as two statements:
update . . .
where last_checked < '1400624137';
insert ignore into proxies(. . .);
(or use on duplicate key update to do nothing).

MySQL: Create unique value constraint between two columns in the *same* row [duplicate]

This question already has answers here:
How to prevent creation of records where the value of two fields is the same?
(3 answers)
Closed 9 years ago.
Is it possible to create a MySQL constraint to force a unique value between two columns in the same row?
For example:
CREATE TABLE Buddies (
User1 int,
User2 int,
) Type = InnoDB;
How would I disallow...
INSERT INTO MyTable SET User1 = '5', User2 = '5' ?
That user would be very lonely otherwise :)
EDIT: the point here is that I would like to do this purely in MySQL and not in the application layer, if possible.
Hi this code makes two column on a row to be unique:
ALTER TABLE 'tableName' ADD UNIQUE( 'column1', 'column2');
With the code above, if you insert value to column1 and column2 identically, it will not be inserted.
For example:
$value1 = 1;
$value2 = 2;
$value3 = 3;
mysql_query("INSERT INTO tableName (column1, column2) VALUES ('$value1', '$value2')"); //This will work.
mysql_query("INSERT INTO tableName (column1, column2) VALUES ('$value1', '$value3')"); //This will work.
mysql_query("INSERT INTO tableName (column1, column2) VALUES ('$value1', '$value2')"); //This WILL NOT work THE SECOND time around because of the unique constraint.
Or refer to this code:
$value1 = 1;
$value2 = 2;
$resultSet = mysql_query("SELECT column1 FROM tableName WHERE column1 = '$value1'");
$rows = mysql_num_rows($resultSet);
if($rows >= 1){
echo $value1 . " already exist.";
}
else{
$query = mysql_query("INSERT INTO tableName (column1, column2) VALUES('$value1','$value2')");
if(){
echo "Value inserted.";
}else echo mysql_error();
}
The code above checks the value of $value1 before inserting the two values to determined if $value1 already exist.
Hope this help you. :-)

SQL - Update multiple records in one query

I have table - config.
Schema:
config_name | config_value
And I would like to update multiple records in one query. I try like that:
UPDATE config
SET t1.config_value = 'value'
, t2.config_value = 'value2'
WHERE t1.config_name = 'name1'
AND t2.config_name = 'name2';
but that query is wrong :(
Can you help me?
Try either multi-table update syntax
UPDATE config t1 JOIN config t2
ON t1.config_name = 'name1' AND t2.config_name = 'name2'
SET t1.config_value = 'value',
t2.config_value = 'value2';
Here is a SQLFiddle demo
or conditional update
UPDATE config
SET config_value = CASE config_name
WHEN 'name1' THEN 'value'
WHEN 'name2' THEN 'value2'
ELSE config_value
END
WHERE config_name IN('name1', 'name2');
Here is a SQLFiddle demo
You can accomplish it with INSERT as below:
INSERT INTO mytable (id, a, b, c)
VALUES (1, 'a1', 'b1', 'c1'),
(2, 'a2', 'b2', 'c2'),
(3, 'a3', 'b3', 'c3'),
(4, 'a4', 'b4', 'c4'),
(5, 'a5', 'b5', 'c5'),
(6, 'a6', 'b6', 'c6')
ON DUPLICATE KEY UPDATE id=VALUES(id),
a=VALUES(a),
b=VALUES(b),
c=VALUES(c);
This insert new values into table, but if primary key is duplicated (already inserted into table) that values you specify would be updated and same record would not be inserted second time.
in my case I have to update the records which are more than 1000, for this instead of hitting the update query each time I preferred this,
UPDATE mst_users
SET base_id = CASE user_id
WHEN 78 THEN 999
WHEN 77 THEN 88
ELSE base_id END WHERE user_id IN(78, 77)
78,77 are the user Ids and for those user id I need to update the base_id 999 and 88 respectively.This works for me.
instead of this
UPDATE staff SET salary = 1200 WHERE name = 'Bob';
UPDATE staff SET salary = 1200 WHERE name = 'Jane';
UPDATE staff SET salary = 1200 WHERE name = 'Frank';
UPDATE staff SET salary = 1200 WHERE name = 'Susan';
UPDATE staff SET salary = 1200 WHERE name = 'John';
you can use
UPDATE staff SET salary = 1200 WHERE name IN ('Bob', 'Frank', 'John');
maybe for someone it will be useful
for Postgresql 9.5 works as a charm
INSERT INTO tabelname(id, col2, col3, col4)
VALUES
(1, 1, 1, 'text for col4'),
(DEFAULT,1,4,'another text for col4')
ON CONFLICT (id) DO UPDATE SET
col2 = EXCLUDED.col2,
col3 = EXCLUDED.col3,
col4 = EXCLUDED.col4
this SQL updates existing record and inserts if new one (2 in 1)
Camille's solution worked. Turned it into a basic PHP function, which writes up the SQL statement. Hope this helps someone else.
function _bulk_sql_update_query($table, $array)
{
/*
* Example:
INSERT INTO mytable (id, a, b, c)
VALUES (1, 'a1', 'b1', 'c1'),
(2, 'a2', 'b2', 'c2'),
(3, 'a3', 'b3', 'c3'),
(4, 'a4', 'b4', 'c4'),
(5, 'a5', 'b5', 'c5'),
(6, 'a6', 'b6', 'c6')
ON DUPLICATE KEY UPDATE id=VALUES(id),
a=VALUES(a),
b=VALUES(b),
c=VALUES(c);
*/
$sql = "";
$columns = array_keys($array[0]);
$columns_as_string = implode(', ', $columns);
$sql .= "
INSERT INTO $table
(" . $columns_as_string . ")
VALUES ";
$len = count($array);
foreach ($array as $index => $values) {
$sql .= '("';
$sql .= implode('", "', $array[$index]) . "\"";
$sql .= ')';
$sql .= ($index == $len - 1) ? "" : ", \n";
}
$sql .= "\nON DUPLICATE KEY UPDATE \n";
$len = count($columns);
foreach ($columns as $index => $column) {
$sql .= "$column=VALUES($column)";
$sql .= ($index == $len - 1) ? "" : ", \n";
}
$sql .= ";";
return $sql;
}
Execute the code below to update n number of rows, where Parent ID is the id you want to get the data from and Child ids are the ids u need to be updated so it's just u need to add the parent id and child ids to update all the rows u need using a small script.
UPDATE [Table]
SET column1 = (SELECT column1 FROM Table WHERE IDColumn = [PArent ID]),
column2 = (SELECT column2 FROM Table WHERE IDColumn = [PArent ID]),
column3 = (SELECT column3 FROM Table WHERE IDColumn = [PArent ID]),
column4 = (SELECT column4 FROM Table WHERE IDColumn = [PArent ID]),
WHERE IDColumn IN ([List of child Ids])
Execute the below code if you want to update all record in all columns:
update config set column1='value',column2='value'...columnN='value';
and if you want to update all columns of a particular row then execute below code:
update config set column1='value',column2='value'...columnN='value' where column1='value'
Assuming you have the list of values to update in an Excel spreadsheet with config_value in column A1 and config_name in B1 you can easily write up the query there using an Excel formula like
=CONCAT("UPDATE config SET config_value = ","'",A1,"'", " WHERE config_name = ","'",B1,"'")
INSERT INTO tablename
(name, salary)
VALUES
('Bob', 1125),
('Jane', 1200),
('Frank', 1100),
('Susan', 1175),
('John', 1150)
ON DUPLICATE KEY UPDATE salary = VALUES(salary);
UPDATE 2021 / MySql v8.0.20 and later
The most upvoted answer advises to use the VALUES function which is now DEPRECATED for the ON DUPLICATE KEY UPDATE syntax. With v8.0.20 you get a deprecation warning with the VALUES function:
INSERT INTO chart (id, flag)
VALUES (1, 'FLAG_1'),(2, 'FLAG_2')
ON DUPLICATE KEY UPDATE id = VALUES(id), flag = VALUES(flag);
[HY000][1287] '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
Use the new alias syntax instead:
official MySQL worklog
Docs
INSERT INTO chart (id, flag)
VALUES (1, 'FLAG_1'),(2, 'FLAG_2') AS aliased
ON DUPLICATE KEY UPDATE flag=aliased.flag;
just make a transaction statement, with multiple update statement and commit. In error case, you can just rollback modification handle by starting transaction.
START TRANSACTION;
/*Multiple update statement*/
COMMIT;
(This syntax is for MySQL, for PostgreSQL, replace 'START TRANSACTION' by 'BEGIN')
Try either multi-table update syntax
Try it copy and SQL query:
CREATE TABLE #temp (id int, name varchar(50))
CREATE TABLE #temp2 (id int, name varchar(50))
INSERT INTO #temp (id, name)
VALUES (1,'abc'), (2,'xyz'), (3,'mno'), (4,'abc')
INSERT INTO #temp2 (id, name)
VALUES (2,'def'), (1,'mno1')
SELECT * FROM #temp
SELECT * FROM #temp2
UPDATE t
SET name = CASE WHEN t.id = t1.id THEN t1.name ELSE t.name END
FROM #temp t
INNER JOIN #temp2 t1 on t.id = t1.id
select * from #temp
select * from #temp2
drop table #temp
drop table #temp2
UPDATE table name SET field name = 'value' WHERE table name.primary key
If you need to update several rows at a time, the alternative is prepared statement:
database complies a query pattern you provide the first time, keep the compiled result for current connection (depends on implementation).
then you updates all the rows, by sending shortened label of the prepared function with different parameters in SQL syntax, instead of sending entire UPDATE statement several times for several updates
the database parse the shortened label of the prepared function , which is linked to the pre-compiled result, then perform the updates.
next time when you perform row updates, the database may still use the pre-compiled result and quickly complete the operations (so the first step above can be omitted since it may take time to compile).
Here is PostgreSQL example of prepare statement, many of SQL databases (e.g. MariaDB,MySQL, Oracle) also support it.

Cancel Insert if inner query find nothing

I got the following query :
INSERT INTO contracts_settings (contract_id, setting_id, setting_value)
VALUES (:contract_id, (
SELECT setting_id
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
), :setting_value)
ON DUPLICATE KEY UPDATE setting_value = :setting_value
The value with the prefix : is replaced with data using PHP PDO::bindBalue.
If the inner query find nothing (it return NULL) but also INSERT a NULL statement. How to avoid that ?
Thanks.
Convert the INSERT ... VALUES syntax to INSERT ... SELECT:
INSERT INTO contracts_settings
(contract_id, setting_id, setting_value)
SELECT
:contract_id,
setting_id,
:setting_value
FROM settings
WHERE setting_type = :setting_type
AND setting_name = :setting_name
LIMIT 1
ON DUPLICATE KEY UPDATE
setting_value = :setting_value ;

mysql updating last inserted id

I want to update a table by getting the last inserted id but it is giving no results.
here is the query :
$quer = mysql_query("UPDATE date
SET d_startdate = '$start', d_enddate = '$end'
WHERE d_id = LAST_INSERT_ID() AND d_sid = $id");
d_id is the primary key and d_sid is a foreign key of another table
I have used INSERT as well as UPDATE operation on my same table and its working fine. You can change this query as per your need.
<?php
$con = mysql_connect("localhost","root","") or die("Could not connect");
mysql_selectdb("test", $con);
$query = 'INSERT INTO item (`name`) VALUES ("DELTaaaA")';
$res = mysql_query($query, $con) or die(mysql_error());
echo "<pre>";
print_r($res);
$query = 'UPDATE item set name="DELTaaaA1" WHERE id = LAST_INSERT_ID()';
$res = mysql_query($query, $con) or die(mysql_error());
print_r($res);
?>
It should return 1 1
use code like this before that
SELECT LAST_INSERT_ID() and assign this to a variable, then use that variable in your code
I don't know the normal syntax, but PDO syntax is quiet simple, you can get last inserted id by the function PDO::lastInsertId() use it as $myPDOobject->lastInsertId() . More information here : http://php.net/manual/en/pdo.lastinsertid.php
LAST_INSERT_ID gives you the id of the most recent insert.
Suppose that you added a row which has d_id=10 (d_id set by auto increment) and d_sid=20 and then another one with d_id=11 (again, auto increment) and d_sid=30.
You then want to look for the most recent insert with d_sid=20, but doing this with LAST_INSERT_ID is not possible, since LAST_INSERT_ID has value 11, and no row matches with that d_id and d_sid=20. You have to keep track by yourself of the most recent d_id for each category, most likely when you insert the new rows.
Do the INSERT
SELECT the LAST_INSERT_ID (name it L_ID)
Store the tuple <d_sid, L_ID> somewhere, so you know that for d_sid your most recent INSERT has value L_ID
UPDATE your table where the d_sid is the one you want and d_id is taken from the tuple
As a side note, mysql_* is deprecated, so you should switch to something else like mysqli or PDO.