I have the following for loops, which should insert values into a mysql table. There is a users array and it is looping over the array and calculation statistics, and it should be inserting all the values into the mysql table, but it only inserts the operation done on the first element of the users array and not the rest. It is ignoring the first for loop, and only inserts for the second for loop, even though, I can see that the loops are doing what they are supposed to do, it is just not being inserted into mysql.
for($i=0; $i<count($users); $i++)
{
for($j=$i+1; $j<count($users); $j++)
{
$user1=$users[$i];
$user2=$users[$j];
$dat1=getData($user1);
$dat2=getData($user2);
$union=count(array_unique(array_merge($dat1, $dat2)));
$intersect=count(array_intersect($dat1, $dat2));
$rate=$intersect/$union;
$sql = "INSERT IGNORE into dat_net VALUES ($user1,$user2,$union,$intersect,$rate)";
$sqlresults = mysql_query($sql);
echo " ".$user1." ".$user2." \n";
if ($sqlresults === false) {
// An error has occured...
echo mysql_error();
}
}
}
Solved due to tips in the comments: I had inadvertently set up keys for the columns, so it wasn't inserting due to duplication.
First of all insert all data using one query. Generate it in for loop and call mysql query once.
You can check if your generated query works simply by echo it before execute and try to run it using some sql client.
try this,
$sql = "INSERT IGNORE into dat_net VALUES ('{$user1}','{$user2}','{$union}','{$intersect}','{$rate}')";
But it will be good if you create a insert query in foreach loop and then fire it once after completing foreach loop.
Related
My entry form I have an inventory database with tables like aluminium, iron etc... Each table contains a subcategory of items like aluminium_pala, iron_1.5inch and so on. The entry code is like this:
include("dbConnect.php");
$orderNo = $_POST["number"];
if(isset($_POST["mat1"])&&$_POST["mat1"]!=NULL)
{
$mat1 = $_POST["mat1"];
$selmat1 = $_POST["selmat1"];
$amtmat1 = $_POST["amtmat1"];
$query = "INSERT INTO $mat1 ($selmat1,orderNo) VALUES (-$amtmat1,$orderNo);";
if(!($result = $mysqli->query($query)))
print "<div class='error'>insertion failed. Check your data</div>";
}
if(isset($_POST["mat2"])&&$_POST["mat2"]!=NULL)
{
$mat2 = $_POST["mat2"];
$selmat2 = $_POST["selmat2"];
$amtmat2 = $_POST["amtmat2"];
$query = "INSERT INTO $mat2 ($selmat2,orderNo) VALUES (-$amtmat1,$orderNo);";
if(!($result = $mysqli->query($query)))
print "<div class='error'>insertion failed. Check your data</div>";
}... and it goes on till mat11
I am trying to collect each similar table (mat1, mat2..) and their corresponding item (selmat1, selmat2...) and bunch the all in one query. That is, instead of going
INSERT INTO al_openable (zPala,orderNo) VALUES (23,14);
INSERT INTO al_openable (outer,orderNo) VALUES (50,14);
I am trying to execute it like
INSERT INTO al_openable (zPala,outer,orderNo) VALUES (23,50,14);
I need this to avoid duplicate foreign key entry(for $orderNo). One idea I've been considering is to use UPDATE if the order number is pre-existing. Do you guys think this is a good idea? And if so, what will be the best way to execute it? If not, how would a more experienced programmer solve this conundrum?
I think this question is related to your query: Multiple Updates in MySQL
You may use ON DUPLICATE KEY UPDATE in combination with INSERT statement.
I'm trying to get better at using PDO, I have this code:
$answers_count = count($answers);
$save_answers = $conn->prepare("INSERT INTO answers (answer, is_correct, question_id) VALUES (:answer, :is_correct, :question_id)");
for($i = 0; $i < $answers_count; $i++) {
$save_answers->bindParam(':answer', $answers[$i]);
$save_answers->bindParam(':is_correct', $answers_state[$i]);
$save_answers->bindParam(':question_id', $last_insert_id);
$save_answers->execute();
}
This code works for me well, but I have read that I should call execute() method just once, if I understood it correctly, I have to prepare sql statement once and execute it after I bind params? If I use execute() method for inserting one new record at a time it works, but if place $save_answers->execute(); statement outside of for loop only one INSERT query will be executed.
am I doing something wrong here, is there other easier way to bind values from the array where each time the number of array elements can be different.
Thank you in advance for the information you can provide me.
but if place $save_answers->execute(); statement outside of for loop only one INSERT query will be executed.
This is because if you place the execute statement outside of your loop it will only execute the query once for the values bound from the last iteration of the for loop. Therefore your current code is correct and rebinding and re-executing the query should be the way to go.
The query needs to bind the values from each iteration (each answer has different values and thus, each insertion has different insertion values). Obviously you need to re-bind the values from each answer, so doing it once will not cut it for you.
If you don't want to execute it via a for loop, you can try batch insertion:
PDO Prepared Inserts multiple rows in single query
This will allow you to do the insertion of multiple rows in one request to the database, which might be what you are looking for.
prepare query first and then execute
$answers_count = count($answers);
$writeArguments = array();
$writeQuery="insert into $tableName (answer, is_correct, question_id) values ";
for($i = 0; $i < $answers_count; $i++) {
if (i > 0) {
$writeQuery .= ',';
}
$writeQuery .= '(?,?,?)';
array_push($writeArguments, $answers[$i], $answers_state[$i], $last_insert_id);
}
$save_answers = $conn->prepare($writeQuery);
$save_answers->execute($writeArguments);
There is a huge two dimensional array which contain 500k sub one dimension arrays, every sub array contain 5 elements.
Now it is my job to insert all the data into a sqlite database.
function insert_data($array){
Global $db;
$dbh=new PDO("sqlite:{$db}");
$sql = "INSERT INTO quote (f1,f2,f3,f4,f5) VALUES (?,?,?,?,?)";
$query = $dbh->prepare($sql);
foreach($array as $item){
$query->execute(array_values($item));
}
$dbh=null;
}
I want to optimize the data insert process that the execute action will be executed for 500k times,how to make it executed just one time?
The idea is to prevent running transactions for each insert, because it will be very slow indeed. So just start and commit the transaction, say for every 10k records.
$dbh->beginTransaction();
$counter = 0;
foreach($array as $item) {
$query->execute(array_values($item));
if ($counter++ % 10000 == 0) {
$dbh->commit();
$dbh->beginTransaction();
}
}
$dbh->commit();
Another solution, you can move an array in a csv file and then just import it.
If you are using a newer version of Sqlite (3.7.11+) then it supports batch inserts:
INSERT INTO quote (f1,f2,f3,f4,f5) VALUES
(?,?,?,?,?),
(?,?,?,?,?),
(?,?,?,?,?);
You can use this to chunk your array into groups, and do batch inserts this way.
As pointed out by Axalix you should also wrap the whole operation in a transaction.
I have a string array and I am trying to insert each data in this array into mySQL inside a foreach loop. But I recognized It doesn't insert all of them. Sometimes insert all, sometimes insert some of them. My code is below. Please let me figure out what my problem here is.
foreach($cbarray as $chvalue){
list($kid, $odemeopt) = explode('-',$chvalue);
$i_tr="trp".$kid;
$i_en="enp".$kid;
$i_fr="frp".$kid;
$tr_kargop=doubleval($_POST[$i_tr]);
$en_kargop=doubleval($_POST[$i_en]);
$fr_kargop=doubleval($_POST[$i_fr]);
if($odemeopt==1){
$ik_tr="trk".$kid;
$ik_en="enk".$kid;
$ik_fr="frk".$kid;
}
$tr_kargoextra=doubleval($_POST[$ik_tr]);
$en_kargopextra=doubleval($_POST[$ik_en]);
$fr_kargopextra=doubleval($_POST[$ik_fr]);
$myquery = "INSERT INTO item_kargo(product_id,kargo_id,kargo_priceTR,kargo_priceEN,kargo_priceFR,odemefarkiTR,odemefarkiEN,odemefarkiFR) VALUES ('$next_increment','$kid','$tr_kargop','$en_kargop','$fr_kargop','$tr_kargoextra','$en_kargopextra','$fr_kargopextra')";
echo "<h2>".$myquery."</h2>";
$kargo_bilgisi=mysql_query($myquery) or die("!!hata kargooo :".mysql_error());
}
This is the result of myquery
INSERT INTO item_kargo(product_id,kargo_id,kargo_priceTR,kargo_priceEN,kargo_priceFR,odemefarkiTR,odemefarkiEN,odemefarkiFR) VALUES ('4','1','1','1','1','','','')
INSERT INTO item_kargo(product_id,kargo_id,kargo_priceTR,kargo_priceEN,kargo_priceFR,odemefarkiTR,odemefarkiEN,odemefarkiFR) VALUES ('4','2','2','2','2','','','')
INSERT INTO item_kargo(product_id,kargo_id,kargo_priceTR,kargo_priceEN,kargo_priceFR,odemefarkiTR,odemefarkiEN,odemefarkiFR) VALUES ('4','4','3','3','3','3','3','3')
If can't you get your error from mysql_error() you can "echo" your data with var_dump(), so you can see how your array is build up. This helps me often to figure out my error in some loops.
I have an array stored in a variable $contactid. I need to run this query to insert a row for each contact_id in the array. What is the best way to do this? Here is the query I need to run...
$contactid=$_POST['contact_id'];
$eventid=$_POST['event_id'];
$groupid=$_POST['group_id'];
mysql_query($query);
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid','$groupid')";
Use a foreach loop.
$query = "INSERT INTO attendance (event_id,contact_id,group_id) VALUES ";
foreach($contactid as $value)
{
$query .= "('{$eventid}','{$value}','{$groupid}'),";
}
mysql_query(substr($query, 0, -1));
The idea here is to concatenate your query string and only make 1 query to the database, each value-set is separated by a comma
Since no one hasn't stated that yet, you actually cannot do this:
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1]);
INSERT INTO [Table] ([Column List])
VALUES ([Value List 2]);
';
mysql_query($query);
as this has been prevented to prevent sql injections in the mysql_query code. You cannot have semicolon within the given query param with mysql_query. With the following exception, taken from the manual comments:
The documentation claims that "multiple queries are not supported".
However, multiple queries seem to be supported. You just have to pass
flag 65536 as mysql_connect's 5 parameter (client_flags). This value
is defined in /usr/include/mysql/mysql_com.h:
#define CLIENT_MULTI_STATEMENTS (1UL << 16) /* Enable/disable multi-stmt support */
Executed with multiple queries at once, the mysql_query function will
return a result only for the first query. The other queries will be
executed as well, but you won't have a result for them.
That is undocumented and unsupported behaviour, however, and easily opens your code to SQL injections. What you can do with mysql_query, instead, is
$query = '
INSERT INTO [Table] ([Column List])
VALUES ([Value List 1])
, ([Value List 2])
[...]
, ([Value List N])
';
mysql_query($query);
so you can actually insert multiple rows with a one query, and with one insert statement. In this answer there's a code example for it which doesn't concatenate to a string in a loop, which is better than what's suggested in this thread.
However, disregarding all the above, you're probably better of still to use a prepared statement, like
$stmt->prepare("INSERT INTO mytbl (fld1, fld2, fld3, fld4) VALUES(?, ?, ?, ?)");
foreach($myarray as $row)
{
$stmt->bind_param('idsb', $row['fld1'], $row['fld2'], $row['fld3'], $row['fld4']);
$stmt->execute();
}
$stmt->close();
Use something like the following. Please note that you shouldn't be using mysql_* functions anymore, and that your code is suseptible to injection.
for ($i = 0; $i < count($contactid); $i++) {
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$eventid','$contactid[$i]','$groupid')";
mysql_query($query);
}
I'm not sure running multiple queries is the best thing to do, so won't recommend making a for loop for example, that runs for each element of the array. I would rather say, make a recursive loop, that adds the new elements to a string, that then gets passed to the query. In case you can give us a short example of your DB structure and how you'd like it to look like (i.e. how the array should go into the table), I could give you an example loop syntax.
Cheers!
What about:
$contactIds = $_POST['contact_id'];
$eventIds = $_POST['event_id'];
$groupIds = $_POST['group_id'];
foreach($contactIds as $key => $value)
{
$currentContactId = $value;
$currentEventId = $eventIds[$key];
$currentGroupId = $groupIds[$key];
$query="INSERT INTO attendance (event_id,contact_id,group_id) VALUES ('$currentEventId','$currentContactId','$currentGroupId')";
mysql_query($query);
}
Well, you could refactor that to insert everything in a single query, but you got the idea.