Related
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´m trying to use CONCAT in a mysql UPDATE.
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
$query_params = array(
':objekt_nr' => $_POST['objekt_nr']);
I have tried several:
objekt_status = VALUES(CONCAT(objekt_status, objekt_status))";
objekt_status = VALUES(CONCAT(objekt_status, 'addMe'))";
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
objekt_status = VALUES((CONCAT(objekt_status, 'salj,$fakt')))";
Error Code for:
objekt_status = VALUES(CONCAT(objekt_status, 'salj,$fakt'))";
...syntax to use near '(objekt_status, 'salj,fakt,'))'
How should the code look like?
You have an semicolon where there should be a comma (after VALUES(objekt_nr);), and it appears the apostrophe is in the wrong place on the last line at $fakt. VALUES is only required for the INSERT, manual here
This query should be correct:
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_nr = objekt_nr,
objekt_status = CONCAT(objekt_status, 'salj,$fakt')";
Also please ensure your variables are escaped, or use a prepared statement.
Try removing values as well as semicolon from the query
"INSERT INTO table (
objekt_nr,
objekt_status)
VALUES(
:objekt_nr,
'salj,$fakt')
ON DUPLICATE KEY UPDATE
objekt_nr = objekt_nr,
objekt_status = CONCAT(objekt_status, 'salj,'$fakt)";
Actually in my case i needed the "Values" for every line but the CONCAT line.
objekt_created_when = VALUES(objekt_created_when),
objekt_status = CONCAT(objekt_status, 'salj,$fakt') ";
If i did remove VALUES from all rows, values in db, got empty!
How can you make one query of this two?? I will insert data into two tables.
$query = "
INSERT INTO dc_mail_users (
i_id_pk, c_user, c_passwd_md5, i_user_active_id_fk, i_user_type_id_fk
) VALUES (
%1%, %2%, %3%, %4%, %5%
)";
$query2 = "
INSERT INTO dc_mail_user_data (
i_id_ut, c_user_sex, c_user_name, c_user_surname, c_user_url
) VALUES (
%1%, %2%, %3%, %4%, %5%
)";
You cannot insert into 2 tables with one query.
You would need to use a stored procedure where you can put that inserts.
What's the purpose of this? Are you trying to insert data into two different tables from one HTML form? I don't know about stored procedures but I use a transaction in similar case like this:
$d = dbSingle::dbLink();
//set autocommit to false
mysqli_autocommit($d->getDbc(), FALSE);
$query = " INSERT INTO dc_mail_users (
i_id_pk, c_user, c_passwd_md5, i_user_active_id_fk, i_user_type_id_fk
) VALUES (
%1%, %2%, %3%, %4%, %5%
)";
$r = $d->sqlQ($query);
//get the last inserted id for the second query
$last_insert_id = $d->getInsertId();
$query2 = "
INSERT INTO dc_mail_user_data (
i_id_ut, c_user_sex, c_user_name, c_user_surname, c_user_url
) VALUES (
%{$last_insert_id}%, %2%, %3%, %4%, %5% //not sure about the syntax, sorry
)";
$r2 = $d->sqlQ($query2);
//rollback if either one of the queries failed
if (!$r || (isset($r2) && !$r2)) {
mysqli_rollback($d->getDbc());
}
else {
//commit if everything worked
mysqli_commit($d->getDbc());
//autocommit on
mysqli_autocommit($d->getDbc(), TRUE);
}
This assumes i_id_ut in the table dc_mail_user_data is the FK and the i_id_pk is an auto increment field. I have a class called dbSingle that contains the query functions and database connection. Hope it's clear enough to be used with regular mysqli functions.
You can do with trigger or stored procedures but not with simple insert query.
$query = "
INSERT INTO dc_mail_users
(i_id_pk, c_user, c_passwd_md5, i_user_active_id_fk, i_user_type_id_fk)
VALUES (%1%, %2%, %3%, %4%, %5%)
";
$query2 = "
INSERT INTO dc_mail_user_data
(c_user_sex, c_user_name, c_user_surname, c_user_url)
VALUES (%1%, %2%, %3%, %4%)";
// start query 1
$dbh = new DB_Mysql_Extended;
$dbh->prepare($query)->execute($this->i_id_pk, $this->c_user, $this->c_passwd_md5, $this->i_user_active_id_fk, $this->i_user_type_id_fk);
// start query 2
$dbh2 = new DB_Mysql_Extended;
$dbh2->prepare($query2)->execute($this->c_user_sex, $this->c_user_name, $this->c_user_surname, $this->c_user_url);
You know, you can duplicate an entry in a table like so;
INSERT INTO `clubs`( `id_leagues`, `name`, `created`) SELECT id_leagues, name, created FROM clubs WHERE id = 36 LIMIT 1
..where my primary key "id" is an auto_increment integer
My question is, is there a way to create ... say 10 entries in a similar way, without using a loop in my php script. Maybe a loop in mysql?
thanks for help
UPDATE
It should insert the same column 10 times.
If you wish to insert 10 records with the same conditions:
INSERT INTO `clubs`( `id_leagues`, `name`, `created`)
SELECT id_leagues, name, created FROM clubs WHERE id = 36 LIMIT 10
And with another conditions:
INSERT INTO `clubs`( `id_leagues`, `name`, `created`)
SELECT id_leagues, name, created FROM clubs WHERE id IN (36,37,38,40,45,55)
And in PHP if you queries are too complicated to use INSERT INTO ... SELECT, you can select required data, form a single bulk insert query and execute it:
$query = "SELECT id_leagues, name, created FROM clubs WHERE id = 36 LIMIT 1";
$result = mysql_query($query);
$row = mysql_fetch_array($result, MYSQL_NUM));
$data = array_fill(0, 9, "('".mysql_real_escape_string($row[0])."', '".mysql_real_escape_string($row[1])."', '".mysql_real_escape_string($row[2])."')");
$query = "INSERT INTO `clubs`( `id_leagues`, `name`, `created`) VALUES " . implode(',', $data);
mysql_query($query);
No problem :) Select more than one tupel in your select statement.
INSERT INTO "table" ("col1", "col2", ...)
SELECT "col3", "col4", ...
FROM "table2"
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();