speed up execution by foreach loop in MySql command - php

I have a PHP foreach statement, looping through a large number of $icons.
For each icon, the DB-column sequence needs to be updated. As follows:
foreach ($icons as $key => $icon) {
// MySql pseudo-code:
UPDATE `tbl_icon2album`
SET `sequence`= $key +1
WHERE iconID= $icon['id']
}
My problem: this becomes very slow for a large number of icons.
My question: Can I speed this up by executing one MySql command that would somehow include the foreach loop?
Much obliged...

You could put all your updates in another table, and update using a single query, e.g.
UPDATE tbl_icon2album, some_other_table
SET sequence = some_other_table.new_key_value
WHERE iconID = some_other_table.icon_reference

How many keys are you updating? Is it the iteration that is slow, or are you doing this thousands of times?
You could use the "in" clause.
ie:
update table set key=key+1 where blah in ('1','2','3');
and you could iterate through the for loop to construct a variable passed to in:
ie:
$iconlist = "";
foreach ($icons as $key => $icon) {
if (!$iconlist) { $iconlist = "($icon" }
else
{ $iconlist .= ",$icon" }
}
if ($iconlist) {
$iconlist .= ")";
$query = "update table set key=key+1 where icon in $iconlist";
}

If you use prepared statements then you can prepare the query once, bind the parameters, and then execute within the loop. This could be faster as it is usually preparing the query that takes up time. For example:
$stmt = $mysqli->prepare("
UPDATE
`tbl_icon2album`
SET
`sequence` = ?
WHERE
`iconID` = ?
");
$stmt->bind_param('ii', $sequence, $icon_id);
foreach ($icons as $key => $icon)
{
$sequence = $key + 1;
$icon_id = $icon['id'];
$stmt->execute();
}

Related

How to change my PHP foreach looped SQL-Insert into a prepared-statement SQL loop?

I have a looped query to do inserts into the MySQL database it works perfectly to do what I need it to do as in it takes all the users inputs in array and then loops them and inputs each into their own row in the database.
$sql_insert_race_history = "INSERT INTO inf_race_history
(`inf_id`,`race_history`, `results`)
VALUES ";
if ($vracehistory != '') {
foreach ($vracehistory as $kay => $value) {
// $sql .= '' | $sql = $sql . '';
$sql_insert_race_history .= "('$inserted_id','{$value}','{$results[$kay]}'),";
}
} else {
$vracehistory = '';
}
// remove last `,` into query;
$sql_insert_race_history = rtrim($sql_insert_race_history, ',');
$countRow = count($_POST['racehist']);
//INSERT INTO THE DATABASE VIA QUERY
$results_racehistory = mysqli_query($vconn, $sql_insert_race_history);
This code works and inserts everything as i need it However i have been told that it is vulnerable to SQL injections attacks, so i have been trying to prevent that by using prepared statements every version I try only so far loops the dont work and it only uploads the very last item in the array
$stmtrace = $conn->prepare("INSERT INTO inf_race_history
(`inf_id`,`race_history`, `results`)
VALUES (?,?,?)");
if ($vracehistory != '') {
foreach ($vracehistory as $kay => $value) {
$stmtrace->bind_param("sss", $inserted_id,$value,$results[$kay]);
}
} else {
$vracehistory = '';
}
// remove last `,` into query;
$sql_insert_race_history = rtrim($stmtrace, ',');
$countRow = count($_POST['racehist']);
//INSERT INTO THE DATABASE VIA QUERY
$stmtrace->execute();
I think it may have something to do with changing it from .= in the foreach loop to just ->bind_param as maybe that is taking away the opportunity to loop it ? tho im not too sure and also how would i echo that i try to echo $stmtrace tho it says method _tostring is not implemented
foreach ($vracehistory as $kay => $value) {
$stmtrace->bind_param("sss", $inserted_id, $value, $results[$kay]);
$stmtrace->execute();
}
You should place execute() inside loop.
bind the params outside the foreach loop, and assign and execute the query when you assign the variables inside the foreach loop. For example
$stmtrace->bind_param("sss", $insertId, $insertValue, $insertKey);
foreach ($vracehistory as $kay => $value) {
$insertId = inserted_id;
$insertValue = $value;
$insertKey = $kay;
$stmtrace->execute();
}
Another note, if you bind an integer, the value of the bind_param method should be 'i'.

how can i insert data into two table at a time?

I need to execte both querys, but insertion will happen on one table(first query only). If i put query9 first, it will execute, otherwise query3.
$query9 = $con->prepare("INSERT INTO complete_status (ID, hotel_id,
floor_id, room_id, pull_chrdsw_status, emergency_status, nurse_callsw_status, cmr_status, foodsw_status, bedside_cancelsw_status ,nurse_distress_status, bcssw_status ,final_status,date1, Time) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,CURRENT_TIMESTAMP,CURRENT_TIMESTAMP)");
$query9->bind_param("iiiiiiiiiiiii", $ID, $HotelID ,$SectorID, $RoomID, $pull_chrdsw_status, $emergency_status, $nurse_callsw_status, $cmr_status, $foodsw_status,$bedside_cancelsw_status, $nurse_distress_status, $bcssw_status,$statuss);
if($value->NurseCallSwStats != $Uploadedpkt->RoomStatus[$key]->NurseCallSwStats)
{
if($DebugMode===TRUE)// Test mode with debugg outputs
{
echo "<br>";
echo "laundry change";
}
$Difference_Flag=TRUE;
$nurse_callsw_status = $Uploadedpkt->RoomStatus[$key]->NurseCallSwStats;
$query3->execute();
$query9->execute();
}
foreach ($Uploadedpkt->RoomStatus as $key => $value)
{
$nurse_callsw_status = $Uploadedpkt->RoomStatus[$key]->NurseCallSwStats;
$query3->execute();
$query9->execute();
}
you can create a stored procedure that contains all your queries and then execute it.

Yii insert series of data

So, I got a series of data that I need to insert into a table. Right now I am using a for loop to iterate through each entry and save the model one by one. But that doesn't seem like a good way to do it, moreover using transaction would be an issue. What's a better way to do it to improve performance and also so I can use transaction.Here's the code I am currently using.
foreach ($sheetData as $data)
{
$newRecord = new Main;
$newRecord->id = $data['A'];
$newRecord->name = $data['B'];
$newRecord->unit = $data['C'];
$newRecord->save();
}
If you can skip validation, you can generate a simple sql insert and execute it once. like:
$count = 0;
$sql = '';
foreach ($sheetData as $data)
{
if(!$count)
$sql .= 'INSERT INTO tbl_main (id ,name ,unit) Values ('.$data['A'].','$data['B']','$data['C']') ';
else
$sql .= ' , ('.$data['A'].','$data['B']','$data['C']')';
$count++;
}
Yii::app()->db->createCommand($sql)->execute();

Insert array into MySQL

I am super confused and have been searching. But as the title suggests I am trying to enter an array.
My question is how do I get this array to import into the database? As of now with the current script, it only imports the first record and not the rest. Here also, I am able to import other values within the same array this is a JSON call by the way and its already being decoded.
foreach ($output as $key => $value) {
if (isset($output[$key]["stats"]["damage_given"]["vehicle"])) {
$damage_given[$key] = $output[$key]["stats"]["damage_given"]["vehicle"];
foreach ($damage_given[$key] as $vehicle_name) {
$vehicle_dmg_id = $vehicle_name['id'];
$vehicle_dmg_name = $vehicle_name['name'];
$vehicle_dmg_value = $vehicle_name['value'];
$vehicle_dmg_faction_nc = $vehicle_name['faction']['nc'];
$vehicle_dmg_faction_tr = $vehicle_name['faction']['tr'];
$vehicle_dmg_faction_vs = $vehicle_name['faction']['vs'];
}
}
}
$add_dmg_veh = "INSERT INTO damage_given(character_number, vehicle_id,
vehicle_name, total_value, vehicle_faction_nc, vehicle_faction_tr,
vehicle_faction_vs) VALUES ('$character_id[$key]', '$vehicle_dmg_id',
'$vehicle_dmg_name','$vehicle_dmg_value', '$vehicle_dmg_faction_nc',
'$vehicle_dmg_faction_tr','$vehicle_dmg_faction_vs')";
Although it is not recommended to store an array in a database, you could serialize() your array to store it in a database. Basically, PHP will convert the array into a specially crafted string, which it can later interpret.
Serialize to store it in the database, and unserialize it to work with it when you pull it out of the database
Note: I say serialization is not recommended, because your database is then not in First Normal Form, specifically because you are storing non-atomic values inside of a particular entry in the database. For this case, I would recommend creating a separate table which can store these values individually, and link the two tables together with a foreign key.
You should be looking about PDO_MySQL and your insert string is outside the loop and should be execute inside it.
You have to iterate through the array and insert every field of the array by it's own.
foreach($array as $value) {
// execute your insert statement here with $value
}
First of all you can't insert array in MySQL as you are doing .. Do as with iterating..
foreach ($output as $key => $value) {
if (isset($output[$key]["stats"]["damage_given"]["vehicle"])) {
$damage_given[$key] = $output[$key]["stats"]["damage_given"]["vehicle"];
foreach ($damage_given[$key] as $vehicle_name) {
$vehicle_dmg_id = $vehicle_name['id'];
$vehicle_dmg_name = $vehicle_name['name'];
$vehicle_dmg_value = $vehicle_name['value'];
$vehicle_dmg_faction_nc = $vehicle_name['faction']['nc'];
$vehicle_dmg_faction_tr = $vehicle_name['faction']['tr'];
$vehicle_dmg_faction_vs = $vehicle_name['faction']['vs'];
// if you wants to use insert query then do here.
$add_dmg_veh = "INSERT INTO damage_given(character_number, vehicle_id,
vehicle_name, total_value, vehicle_faction_nc, vehicle_faction_tr,
vehicle_faction_vs) VALUES ('$character_id[$key]', '$vehicle_dmg_id',
'$vehicle_dmg_name', '$vehicle_dmg_value', '$vehicle_dmg_faction_nc',
'$vehicle_dmg_faction_tr', '$vehicle_dmg_faction_vs')";
}
}
}
try building your insert data in an array and then implode the results into a single query:
<?php
foreach ($output as $key => $value) {
if (isset($output[$key]["stats"]["damage_given"]["vehicle"])) {
$damage_given[$key] = $output[$key]["stats"]["damage_given"]["vehicle"];
foreach ($damage_given[$key] as $vehicle_name) {
$sql[] = "
(
".$vehicle_name['id'].",
".$vehicle_name['name'].",
".$vehicle_name['value'].",
".$vehicle_name['faction']['nc'].",
".$vehicle_name['faction']['tr'].",
".$vehicle_name['faction']['vs']."
)";
}
}
}
$query = "
INSERT INTO damage_given
(
character_number,
vehicle_id,
vehicle_name,
total_value,
vehicle_faction_nc,
vehicle_faction_tr,
vehicle_faction_vs
)
VALUES
".implode(",",$sql)."
";
?>
here is what I got to fix the problem!
$stmt = $dbh->prepare(
"INSERT INTO kills_vehicle (character_number, veh_id, veh_name, veh_total, veh_faction_nc, veh_faction_tr, veh_faction_vs)
VALUES(:char_id, :id, :vehname, :total_value, :faction_nc, :faction_tr, :faction_vs)");
foreach ($output as $key => $value) {
if (isset($output[$key]["stats"]["play_time"]["vehicle"])) {
$character_id[$key] = $output[$key]["id"];
$score_hit_count[$key] = $output[$key]["stats"]["kills"]["vehicle"];
foreach ($score_hit_count[$key] as $row) {
$stmt->bindValue(':char_id', $character_id[$key]);
$stmt->bindValue(':id', $row[id]);
$stmt->bindValue(':vehname', $row[name]);
$stmt->bindValue(':total_value', $row[value]);
$stmt->bindValue(':faction_nc', $row[faction][nc]);
$stmt->bindValue(':faction_tr', $row[faction][tr]);
$stmt->bindValue(':faction_vs', $row[faction][vs]);
$stmt->execute();
}
}
}

how to find percentage and save it to mysql

$ar1=array("Mobile","shop","software","hardware");
$arr2=arry("shop","Mobile","shop","software","shop")
i want to compare the elements of arr2 to arr1 i.e
$counts=array();
foreach($arr2 as $val)
{
if(in_array($val, $arr1))
{
array_push($counts,$val);
// here will my insert query to insert data in mysql table.
}
} //end of foreach loop
$specific_fields = array_count_values($counts); /* Array ( [shop] => 3 [software] => 1 [Mobile] => 1)
$total_fields=count($arr2); // output will be 5
Now here first i want to find percentage for each element
i.e $per1=$specific_fields['shop']/$total_fields;
$per2=$per1*100;
$percentage=number_format($per2,0);
when i find the percentage how can i update below query with the percentage values of all elements.
$query="update table_name set shop='$percentage_value',Mobile='$percentage_value'.......";
}
Is there a dynamic way to update all the fields automatically.
Have a look at PDO and prepared statements, and also at MySQL prepared statements.
http://php.net/manual/en/pdo.prepared-statements.php and http://dev.mysql.com/tech-resources/articles/4.1/prepared-statements.html
Use the COUNT function. Example:update table_name set shop=(COUNT(*) FROM table_name WHERE column meets condition)/(COUNT(*) FROM table_name) * 100, Mobile = ...
http://www.tizag.com/mysqlTutorial/mysqlcount.php
$specific_fields = array_map(function($val, $total_fields){
return $val / count($total_fields)
}, $specific_fields, [$arr2]);
print_r($specific_fields);
For update sql statement should be like
$str_temp = '';
foreach ($specific_fields as $key => $f)
{
$str_temp .= "$key=$f"
}
$sql = "UPDATE ... SET $str_temp WHERE ID = <ID>"

Categories