How to update mysql data in bulk ?
How to define something like this :
UPDATE `table`
WHERE `column1` = somevalues
SET `column2` = othervalues
with somevalues like :
VALUES
('160009'),
('160010'),
('160011');
and othervalues :
VALUES
('val1'),
('val2'),
('val3');
maybe it's impossible with mysql ?
a php script ?
The easiest solution in your case is to use ON DUPLICATE KEY UPDATE construction. It works really fast, and does the job in easy way.
INSERT into `table` (id, fruit)
VALUES (1, 'apple'), (2, 'orange'), (3, 'peach')
ON DUPLICATE KEY UPDATE fruit = VALUES(fruit);
or to use CASE construction
UPDATE table
SET column2 = (CASE column1 WHEN 1 THEN 'val1'
WHEN 2 THEN 'val2'
WHEN 3 THEN 'val3'
END)
WHERE column1 IN(1, 2 ,3);
If the "bulk" data you have is dynamic and is coming from PHP (you did tag it, after all), then the query would look something like this:
INSERT INTO `foo` (id, bar)
VALUES
(1, 'pineapple'),
(2, 'asian pear'),
(5, 'peach')
ON DUPLICATE KEY UPDATE bar = VALUES(bar);
and the PHP to generate this from an existing array (assuming the array is of a format like:
$array = (
somevalues_key => othervalues_value
);
) would look something like this (by no means the best (doesn't address escaping or sanitizing the values, for instance), just an quick example):
$pairs = array();
foreach ($array as $key => $value) {
$pairs[] = "($key, '$value')";
}
$query = "INSERT INTO `foo` (id, bar) VALUES " . implode(', ', $pairs) . " ON DUPLICATE KEY UPDATE bar = VALUES(bar)";
You could try an UPDATE with JOIN as below:
UPDATE table
INNER JOIN (
SELECT 1 column1, 2 column2, 10 new_v1, 20 new_v2, 30 new_v3
UNION ALL SELECT 4 column1, 5 column2, 40 new_v1, 50 new_v2, 60 new_v3
) updates
ON table.column1 = updates.column1
AND table.column2 = updates.column2
SET
table.column1 = updates.new_v1,
table.column2 = updates.new_v2,
table.column3 = updates.new_v3;
As long as you can craft the inner SELECT statements from the updates subquery you would get the benefit of running all these updates in a single statement (which should give you some performance boost on InnoDB depending on your table size).
If you are using a drag & drop tableView or collectionView to sort datas in your app, like allowing users to arrange their photos by drag and drop functionality, send a comma seperated list of ordered ids to the backend after user edits finish.
In your backend, explode ids to the an array like
$new_ranks = array();
$supplied_orders = explode(",", $_POST["supplied_new_order"]); //52,11,6,54,2 etc
$start_order = 99999;
foreach ($supplied_orders as $supplied_row_id) {
//your all validations... make sure supplied_row_id belongs to that user or not etc..
$new_ranks[intval($supplied_row_id)] = $start_order--;
}
now, you can update all new ranks like #Farside recommendation 2.
if (count($new_ranks) > 0) {
$case_sqls = array();
foreach ($new_ranks as $id => $rank) {
$case_sqls[] = "WHEN ".intval($id)." THEN ".intval($rank)."";
}
$case_sql = implode(" ", $case_sqls);
$this->db->query("
UPDATE
service_user_medias
SET
rank = (CASE id ".$case_sql." END)
WHERE
id IN(".implode(",", array_keys($new_ranks)).");
");
}
If you have data in array format then try this
and your query is like "UPDATE table WHERE column1 = ? SET column2 = ?"
then set it like below
foreach($data as $key => $value) {
$query->bind_param('ss', $key, $value);
$query->execute();
}
hope it'll work.
Reference from this.
I have a problem regarding SQL Query. I have 3 Insert queries in my code.
the first query is with auto-increment ID.
INSERT INTO master_tbl
The second Insert will get the ID from 1st query using LAST_INSERT_ID()function.
INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES (LAST_INSERT_ID(), '4', '-', '12')
My problem is, I have third query which needed to use the ID generated in the 1st query as its id_ref also.
When I use the LAST_INSERT_ID(), the ID it gets was the ID of the second query.
Any suggestions on how can I still get the ID in the 1st query to use on 3rd?
You can declare the variable and store the first queries id in that variable and then use it wherever you want.
After first query as you mentioned you are using the separate queries you can try using select to set the `Last insert id` into the variable and then use that variable as below,
select #valuetoUse := LAST_INSERT_ID()
Or Other way is use select the to get the value in your code and then pass that value to insert as all other values. For getting value you can directly fire select
SELECT LAST_INSERT_ID()
then in second query
INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES (valuetoUse , '4', '-', '12')
then again in the third query
INSERT INTO thirdtable (id_ref, process_id, hot_cold, temp)
VALUES (valuetoUse , '4', '-', '12')
For more info on how to use user defined variables see here.
Functionality is same as told by #Coder of Code But with PHP
Try This
Create Connection
$conn = new mysqli($servername, $username, $password, $dbname);
First Insert into Table 1
INSERT INTO master_tbl
Then do
$sql = "SELECT MAX(id) as id from master_tbl";
$result = $conn->query($sql);
$row = $result->fetch_array(MYSQLI_NUM);
$latest_id=$row[0];
$sql = "INSERT INTO process (id_ref, process_id, hot_cold, temp)
VALUES ($latest_id,'4','-','12')";
if ($conn->query($sql) === TRUE)
{
echo "New record created successfully";
}
$sql = "INSERT INTO table3 (id_ref , columns list)
VALUES ($latest_id,other fields)";
if ($conn->query($sql) === TRUE)
{
echo "New record created successfully";
}
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 ;
i got two tables and my environment transaction is allowed...
Table A - ID + Name
Table B - ID + Value A+ Value B+ IDTable A
may i know how to write the query to insert value at once ? hope it can be done within single query...just performance is the highest concern.
mysql_query("BEGIN");
$result_1 = mysql_query("INSERT INTO table_a ('name') values ('Chris')");
if( ! $result_1) {
mysql_query("ROLLBACK");
die(); // or handle the error however you choose
}
$table_1_id = mysql_insert_id();
$result_2 = mysql_query("INSERT INTO table_b ('value_a', 'value_b', 'table_a_id') values ('v1', 'v2', $table_1_id)");
if( ! $result_2) {
mysql_query("ROLLBACK");
die(); // or handle the error however you choose
}
mysql_query("COMMIT");
You can't do insert on different tables with a single query.
insert into tableA (name) values ('name');
set #last = last_insert_id();
insert into tableB (valueA,valueB,idtableA) values ('valueA','valueB',#last);
I have a MySQL question that I think must be quite easy. I need to return the LAST INSERTED ID from table1 when I run the following MySql query:
INSERT INTO table1 (title,userid) VALUES ('test',1);
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT LAST_INSERT_ID();
As you can understand the current code will just return the LAST INSERT ID of table2 instead of table1, how can I get the id from table1 even if I insert into table2 between?
You could store the last insert id in a variable :
INSERT INTO table1 (title,userid) VALUES ('test', 1);
SET #last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO table2 (parentid,otherid,userid) VALUES (#last_id_in_table1, 4, 1);
Or get the max id from table1 (EDIT: Warning. See note in comments from Rob Starling about possible errors from race conditions when using the max id)
INSERT INTO table1 (title,userid) VALUES ('test', 1);
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(), 4, 1);
SELECT MAX(id) FROM table1;
(Warning: as Rob Starling points out in the comments)
Since you actually stored the previous LAST_INSERT_ID() into the second table, you can get it from there:
INSERT INTO table1 (title,userid) VALUES ('test',1);
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT parentid FROM table2 WHERE id = LAST_INSERT_ID();
This enables you to insert a row into 2 different tables and creates a reference to both tables too.
START TRANSACTION;
INSERT INTO accounttable(account_username)
VALUES('AnAccountName');
INSERT INTO profiletable(profile_account_id)
VALUES ((SELECT account_id FROM accounttable WHERE account_username='AnAccountName'));
SET #profile_id = LAST_INSERT_ID();
UPDATE accounttable SET `account_profile_id` = #profile_id;
COMMIT;
I had the same problem in bash and i'm doing something like this:
mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');"
which works fine:-) But
mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');set #last_insert_id = LAST_INSERT_ID();"
mysql -D "dbname" -e "insert into table2 (id_tab1) values (#last_insert_id);"
don't work. Because after the first command, the shell will be logged out from mysql and logged in again for the second command, and then the variable #last_insert_id isn't set anymore.
My solution is:
lastinsertid=$(mysql -B -N -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');select LAST_INSERT_ID();")
mysql -D "dbname" -e "insert into table2 (id_tab1) values (${lastinsertid});"
Maybe someone is searching for a solution an bash :-)
We only have one person entering records, so I execute the following query immediately following the insert:
$result = $conn->query("SELECT * FROM corex ORDER BY id DESC LIMIT 1");
while ($row = $result->fetch_assoc()) {
$id = $row['id'];
}
This retrieves the last id from the database.
It would be possible to save the last_id_in_table1 variable into a php variable to use it later?
With this last_id I need to attach some records in another table with this last_id, so I need:
1) Do an INSERT and get the last_id_in_table1
INSERT into Table1(name) values ("AAA");
SET #last_id_in_table1 = LAST_INSERT_ID();
2) For any indeterminated rows in another table, UPDATING these rows with the last_id_insert generated in the insert.
$element = array(some ids)
foreach ($element as $e){
UPDATE Table2 SET column1 = #last_id_in_table1 WHERE id = $e
}
Instead of this LAST_INSERT_ID()
try to use this one
mysqli_insert_id(connection)
For no InnoDB solution: you can use a procedure
don't forgot to set the delimiter for storing the procedure with ;
CREATE PROCEDURE myproc(OUT id INT, IN otherid INT, IN title VARCHAR(255))
BEGIN
LOCK TABLES `table1` WRITE;
INSERT INTO `table1` ( `title` ) VALUES ( #title );
SET #id = LAST_INSERT_ID();
UNLOCK TABLES;
INSERT INTO `table2` ( `parentid`, `otherid`, `userid` ) VALUES (#id, #otherid, 1);
END
And you can use it...
SET #myid;
CALL myproc( #myid, 1, "my title" );
SELECT #myid;
In trigger BEFORE_INSERT this working for me:
SET #Last_Insrt_Id = (SELECT(AUTO_INCREMENT /*-1*/) /*as Last_Insert_Id*/
FROM information_schema.tables
WHERE table_name = 'tblTableName' AND table_schema = 'schSchemaName');
Or in simple select:
SELECT(AUTO_INCREMENT /*-1*/) as Last_Insert_Id
FROM information_schema.tables
WHERE table_name = 'tblTableName' AND table_schema = 'schSchemaName');
If you want, remove the comment /*-1*/ and test in other cases.
For multiple use, I can write a function. It's easy.
For last and second last:
INSERT INTO `t_parent_user`(`u_id`, `p_id`) VALUES ((SELECT MAX(u_id-1) FROM user) ,(SELECT MAX(u_id) FROM user ) );
We could also use $conn->insert_id;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
$sql = "INSERT INTO MyGuests (firstname, lastname, email)
VALUES ('John', 'Doe', 'john#example.com')";
if ($conn->query($sql) === TRUE) {
$last_id = $conn->insert_id;
echo "New record created successfully. Last inserted ID is: " . $last_id;
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
My code does not work for me. Any idea to recover the id of my last insert this is my code I am new developing and I do not know much
I GOT ERROR IN THE QUERY AND I DON'T KNOW HOW TO SEND PRINT IN THE LINE OF $ session-> msg ('s', "Product added successfully. Make cost configuration". LAST_INSERT_ID ());
ALREADY VERIFY AND IT IS CORRECT THE CONNECTION AND THE FIELDS OF THE DATABASE.
<?php
if(isset($_POST['add_producto'])){
$req_fields = array( 'nombre', 'categoria', 'proveedor');
validate_fields($req_fields);
if(empty($errors)){
$codigobarras = remove_junk($db->escape($_POST['codigobarras']));
$identificador = remove_junk($db->escape($_POST['identificador']));
$nombre = remove_junk($db->escape($_POST['nombre']));
$categoria = (int)$db->escape($_POST['categoria']);
$etiquetas = remove_junk($db->escape($_POST['etiquetas']));
$unidadmedida = remove_junk($db->escape($_POST['unidadmedida']));
$proveedor = remove_junk($db->escape($_POST['proveedor']));
$fabricante = remove_junk($db->escape($_POST['idfabricante']));
$maximo = remove_junk($db->escape($_POST['maximo']));
$minimo = remove_junk($db->escape($_POST['minimo']));
$descripcion = remove_junk($db->escape($_POST['descripcion']));
$dias_vencimiento = remove_junk($db->escape($_POST['dias_vencimiento']));
$servicio = "0";
if (isset($_POST['servicio'])){
$servicio =implode($_POST['servicio']);
}
$numeroserie = "0";
if (isset($_POST['numeroserie'])){
$numeroserie =implode($_POST['numeroserie']);
}
$ingrediente = "0";
if (isset($_POST['ingrediente'])){
$ingrediente =implode($_POST['ingrediente']);
}
$date = make_date();
$query = "INSERT INTO productos (";
$query .=" codigo_barras,identificador_producto,nombre,idcategoria,idetiquetas,unidad_medida,idproveedor,idfabricante,max_productos,min_productos,descripcion,dias_vencimiento,servicio,numero_serie,ingrediente,activo";
$query .=") VALUES (";
$query .=" '{$codigobarras}', '{$identificador}', '{$nombre}', '{$categoria}', '{$etiquetas}', '{$unidadmedida}', '{$proveedor}', '{$fabricante}', '{$maximo}', '{$minimo}', '{$descripcion}', '{$dias_vencimiento}', '{$servicio}', '{$numeroserie}', '{$ingrediente}', '1'";
$query .=");";
$query .="SELECT LAST_INSERT_ID();";
if($db->query($query)){
$session->msg('s',"Producto agregado exitosamente. Realizar configuracion de costos" . LAST_INSERT_ID());
redirect('precio_producto.php', false);
} else {
$session->msg('d',' Lo siento, registro falló.');
redirect('informacion_producto.php', false);
}
} else{
$session->msg("d", $errors);
redirect('informacion_producto.php',false);
}
}
?>
Just to add for Rodrigo post, instead of LAST_INSERT_ID() in query you can use SELECT MAX(id) FROM table1;, but you must use (),
INSERT INTO table1 (title,userid) VALUES ('test', 1)
INSERT INTO table2 (parentid,otherid,userid) VALUES ( (SELECT MAX(id) FROM table1), 4, 1)
If you need to have from mysql, after your query, the last auto-incremental id without another query, put in your code:
mysql_insert_id();