Can anyone see what I am doing wrong here? Basically what is supposed to happen is you upload the csv, it then pulls the rows out and checks with the database if that row exists, if it does it updates it, if it doesn't it inserts it. If the row is blank it ignores it.
What is actually happening is when I upload a csv I just get 'updated' for each of the 4 test lines whether it is in the database or not.
Also if anyone can suggest a better way of doing this, or trimming down the code please let me know, as I know by coding isn't the greatest by any stretch of the imagination.
if(isset($_GET['uploadfile'])) {
$file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
while(! feof($file))
{
$line = fgetcsv($file, 0, ',');
list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
$rowcheck = "SELECT * FROM `stock` WHERE `productcode` = '$productcode'";
if (#mysql_num_rows(mysql_query($rowcheck))!=1) {
if ($productcode == NULL OR $productcode == ''){}
else {
$datecreated = date('Y-m-d');
// Insert Posted Data
mysqli_query($db,"INSERT INTO stock (`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
echo $productcode.' - Added<br/ >';
}
}
else{
if ($productcode == NULL OR $productcode == ''){}
else {
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre' WHERE productcode = '$productcode'");
if ($stmt === FALSE) { echo "an error has occured"; }
$stmt->execute();
$stmt->close();
echo $productcode.' - Updated<br/ >';
}
}
}
fclose($file);
}
}
There seemed to be a brace missing which I think would indeed have made it try to update whatever - indented statements to help make it a bit clearer and added mysqli instead of mysql where it appeared to be wrong - assuming everything should be mysqli. Hope that may help.
You will need to add clean-up/sanitizing/escape code but I assume you know that
if(isset($_GET['uploadfile'])){
$file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
while(! feof($file)){
$line = fgetcsv($file, 0, ',');
list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
$rowcheck = "SELECT * FROM `stock` WHERE `productcode` = '$productcode'";
if (#mysqli_num_rows(mysqli_query($rowcheck))!=1){
if ($productcode == NULL OR $productcode == ''){
echo "Product code missing and rowcheck is not 1<br/ >"; // for testing
}else{
$datecreated = date('Y-m-d');
// Insert Posted Data
mysqli_query($db,"INSERT INTO stock (`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
echo $productcode.' - Added<br/ >';
}
}elseif($productcode == NULL OR $productcode == ''){
echo "Product code missing<br/ >"; // for testing
}else{
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre' WHERE productcode = '$productcode'");
if ($stmt === FALSE){
echo "an error has occured<br/ >";
}else{
$stmt->execute();
$stmt->close();
echo $productcode.' - Updated<br/ >';
}
}
}
}
You might also like to look at the security implications of using uploaded files directly by their temp name http://www.acunetix.com/websitesecurity/php-security-4/ among many others.
This is what worked in the end :
if(isset($_GET['uploadfile'])){
$file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
while(! feof($file)){
$line = fgetcsv($file, 0, ',');
list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
$query = mysqli_query($db, "SELECT * FROM stock WHERE productcode='".$productcode."'");
if(mysqli_num_rows($query) > 0){
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm',1litre = '$v1litre',2litre = '$v2litre',3litre = '$v3litre',5litre = '$v5litre',7litre = '$v7litre'
WHERE productcode = '$productcode'");
if ($stmt === FALSE) { echo "an error has occured"; }
$stmt->execute();
$stmt->close();
echo $productcode.' - Updated<br/ >';
}else{
// do something
if (!mysqli_query($db,$query))
{
$datecreated = date('Y-m-d');
// Insert Posted Data
mysqli_query($db,"INSERT INTO stock (`image`,`genusid`,`datecreated`, `productcode`, `9cm`, `1litre`, `2litre`, `3litre`, `5litre`, `7litre`) VALUES ('None.gif','5','$datecreated', '$productcode', '$v9cm', '$v1litre', '$v2litre', '$v3litre', '$v5litre', '$v7litre')") or die ('Unable to execute query. '. mysqli_error());
echo $productcode.' - Added<br/ >';
}
}
}}}
It may be easier to use mysql's ON DUPLICATE KEY UPDATE clause (http://dev.mysql.com/doc/refman/5.7/en/insert-on-duplicate.html).
See hjpotter92's answer here: On Duplicate Key Update same as insert. Your query would need to be modified to something like this:
INSERT INTO table (id,a,b,c,d,e,f,g)
VALUES (1,2,3,4,5,6,7,8)
ON DUPLICATE KEY
UPDATE a=a, b=b, c=c, d=d, e=e, f=f, g=g;
This should allow you to remove most of the conditional logic and also cut down on the number of queries you run.
Related
This question already has answers here:
How to use mysqli prepared statements?
(3 answers)
Closed 8 months ago.
I want to update existing records in a table using an excel csv import file.
the table name is aflossingen and has the columns: AflossingID, VoorschotID, Aflossingdatum, Aflossingsbedrag, Afgelost, Saldo.
This is the code PHPRad has generated, which can only do an INSERT:
function import_data(){
if(!empty($_FILES['file'])){
$finfo = pathinfo($_FILES['file']['name']);
$ext = strtolower($finfo['extension']);
if(!in_array($ext , array('csv'))){
$this->set_flash_msg("Document formaat niet ondersteund", "danger");
}
else{
$file_path = $_FILES['file']['tmp_name'];
if(!empty($file_path)){
$request = $this->request;
$db = $this->GetModel();
$tablename = $this->tablename;
$options = array('table' => $tablename, 'fields' => '', 'delimiter' => ',', 'quote' => '"');
$data = $db->loadCsvData( $file_path , $options , false );
if($db->getLastError()){
$this->set_flash_msg($db->getLastError(), "danger");
}
else{
$this->set_flash_msg("Data imported successfully", "success");
}
}
else{
$this->set_flash_msg("Error uploading file", "danger");
}
}
}
else{
$this->set_flash_msg("No file selected for upload", "warning");
}
$this->redirect("aflossingen");
}
This is my code. Nothing happens:
function import_data(){
if(isset($_POST["importcsv"])){
$file = $_FILES["csv_file"]["tmp_name"];
$handle = fopen($file,"r");
while ($row = fgetcsv($handle)) {
$id = $row[0];
$Aflossingdatum = $row[2];
$Aflossingsbedrag = $row[3];
$Afgelost = $row[4];
$Saldo = $row[5];
$sql = "UPDATE aflossingen SET Aflossingdatum = Aflossingdatum,Afgelost = Afgelost, Saldo = Saldo WHERE AflossingID = AflossingID";
$update_data_stmt = mysqli_stmt_init($connection);
if (!mysqli_stmt_prepare($update_data_stmt, $sql)){
die("Something went wrong with the upload. " . mysqli_error($connection));
} else {
mysqli_stmt_bind_param($update_data_stmt, "ss", $Aflossingdatum, $id, $Aflossingsbedrag, $Afgelost, $Saldo);
mysqli_stmt_execute($update_data_stmt);
if ($id == "AflossingID" && $Aflossingdatum == "Aflossingdatum"){
echo "";
} else {
echo "Lead <b>{$id}</b>'s response was updated to <b>{$Aflossingdatum}</b>.</p>";
}
}
}
}
$this->redirect("aflossingen");
}
You're not creating the prepared statement correctly. It needs to have ? placeholders where the variables will be substituted.
And you need to have as many characters in the type string argument to mysqli_stmt_bind_param() as you have variables. And the variables have to be in the same order as in the query, so $id must be last.
You don't need to prepare the statement and bind parameters each time through the loop. Just prepare it once, and bind the parameters to reference variables that will be updated during the loop.
You were missing Aflossingsbedrag from your UPDATE query, I added it back.
Instead of checking whether $id == 'AflossingID' to skip the header row, I simply read the first line of the file before going into the loop that calls fgetcsv(). If you prefer to do it by checking the column value (in case there's no header) you should do it before executing the query, and skip the update (you can use continue; to go to the next iteration of the loop)
function import_data(){
if(isset($_POST["importcsv"])){
$file = $_FILES["csv_file"]["tmp_name"];
$handle = fopen($file,"r");
$sql = "UPDATE aflossingen SET Aflossingdatum = ?, Aflossingsbedrag = ?, Afgelost = ?, Saldo = ? WHERE AflossingID = ?";
$update_data_stmt = mysqli_stmt_init($connection);
mysqli_stmt_bind_param($update_data_stmt, "sssss", $Aflossingdatum, $Aflossingsbedrag, $Afgelost, $Saldo, $id);
if (!mysqli_stmt_prepare($update_data_stmt, $sql)){
die("Something went wrong with the upload. " . mysqli_error($connection));
}
fgets($handle); // Skip header row
while ($row = fgetcsv($handle)) {
$id = $row[0];
$Aflossingdatum = $row[2];
$Aflossingsbedrag = $row[3];
$Afgelost = $row[4];
$Saldo = $row[5];
if (mysqli_stmt_execute($update_data_stmt)) {
echo "Lead <b>{$id}</b>'s response was updated to <b>{$Aflossingdatum}</b>.</p>";
} else {
echo "Something went wrong when updating $id. " . mysqli_stmt_error($update_data_stmt);
}
}
}
}
I already took advises on the web regarding to prevent duplicate values from saving to the mysql table but it still saves it and I already placed echo statements and exit to ensure this doesn't happen but it still has. Here is the code that I used and edited to my preferences:
$line = array();
$file = fopen("D:/Documents/Documents/LOGS.txt", "r");
while (! feof($file))
{
$line[] = fgetcsv($file, 4096);
foreach ($line as $value)
{
$newline = explode(" ", $value[1]);
$date = trim($newline[0]);
$time = trim($newline[1]);
$check = mysqli_query($cxn, "select * from temprec where EmpID = '$value[0]'
and ValidDate = '$date' and ValidTime = '$time'") or die("Couldn't execute
query");
$checkrows = mysqli_num_rows($check);
if ($checkrows > 0) {
echo "data already saved";
exit;
}
else
{
$result = mysqli_query($cxn, "insert ignore into
temprec(EmpID,ValidDate,ValidTime) values('$value[0]','$date','$time')") or
die("Couldn't execute query");
}
}
}
fclose($file);
Note: the logs.txt contains data from a biometrics machine and it contains too much duplicate values.
You have a mistake in the check query. In string
"select * from temprec where EmpID = '$value[0]' and ValidDate = '$date' and ValidTime = '$time'" variable $value[0] parces as just $value and you get query like this "select * from temprec where EmpID = 'array[0]' and ValidDate = '$date' and ValidTime = '$time'".
Using '{}' should fix it: "select * from temprec where EmpID = '${value[0]}' and ValidDate = '$date' and ValidTime = '$time'".
have you tried echoing your "insert ignore into temprec(EmpID,ValidDate,ValidTime) values('$value[0]','$date','$time')") or
die("Couldn't execute query" for you to be sure if your query shows the right query?
I'm preparing some statements and want to check if the row exists before I update. If it exists then update it, if it doesn't then output a message "No such animal". I have the update bit working, but unsure how to check if the row exists. Please assist.
$v = array();
$v[] = $_POST['status'];
$v[] = $_POST['id'];
$dbh = dbh_get();
$sql = 'UPDATE tap SET status=?
WHERE id =?';
$stmt = $dbh->prepare($sql);
$stmt->execute($v);
\\ if row isn't there display message "No such animal"
\\ otherwise print the below
printf("Status was changed to - %s", $v[0]);
\\then either way have my continue button for me to click on
print '<div class="button" style="float:left;" onclick="window.location.href=\'admin.php\';">Admin</div>' . "\n";
dbh_free($dbh)
According to your question, you want to check if the row exists before performing update. you can try this -
$id_exist = 0;
$sql = "SELECT id
FROM tap" ;
$sql_prepare = $dbh->prepare($sql);
$sql_prepare->execute();
while($row = $sql_prepare->fetchObject()) {
if($_POST['id'] == $row->id) {
$id_exist = 1;
}
}
if($id_exist == 1) {
// perform update here
} else {
echo 'No such animal';
}
So the user uploads a stock file csv with all of the products in. The file is formatted are follows :
productcode,size1,size2,size3,size4,size5
and has that info for each product line.
I have the following code which deals with the uploaded file and pulls that info from the file.
<?php
if (isset($_GET['uploadfile'])) {
$file = fopen($_FILES['csvfile']['tmp_name'], 'r+');
while(!feof($file)) {
$line = fgetcsv($file, 0, ',');
list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm', 1litre = '$v1litre', 2litre = '$v2litre', 3litre = '$v3litre', 5litre = '$v5litre', 7litre = '$v7litre' WHERE productcode = '$productcode'");
if ($stmt === FALSE) {
echo "an error has occured";
}
$stmt->execute();
$stmt->close();
}
fclose($file);
}
?>
It seems to work fine and is updating each record in the database as expected, the problem I am having is if I insert a new product code.....lets say bob, so
bob,11,44,54,23,12
This code 'bob' isn't in the database, so cannot be updated, so there should in theory be an error, but no error is being shown ?.
How would your database-server know that you expect exactly 1 row to be updated? Either check that explicitly or verify the productcode using a SELECT before updating it
Generally before going for update we should always want to check weather that data is available in DB to update, so here in your code before updating the product check weather the productcode is available in db
For eg your code should look like this:
while(!feof($file)) {
$line = fgetcsv($file, 0, ',');
list($productcode, $v9cm, $v1litre, $v2litre, $v3litre, $v5litre, $v7litre) = $line;
// check productcode available in db
$product_stmt = $db->prepare("SELECT * FROM stock WHERE productcode= '$productcode'");
$product_stmt->execute();
$product_details = $product_stmt->fetch(PDO::FETCH_ASSOC);
if($product_details) {
$stmt = $db->prepare("UPDATE stock SET 9cm = '$v9cm', 1litre = '$v1litre', 2litre = '$v2litre', 3litre = '$v3litre', 5litre = '$v5litre', 7litre = '$v7litre' WHERE productcode = '$productcode'");
if ($stmt === FALSE) {
echo "an error has occured";
}
$stmt->execute();
$stmt->close();
} else {
// your insert query
// or
echo "Product code ".$productcode." not available in DB";
}
}
PHP provides affected_rows API for MySQL exactly for this purpose.
Trying to insert some data from a csv file using php command fcsvget into a mysql table but coming up short can anyone tell me where im going wrong. im getting no data going in and errors when loading the page.
the csv file has different header names and amount of columns that the table it is going into.
here is my code so far.
<?php
// set local variables
$connect = mysql_connect("localhost","db","password") or die('Could not connect: ' . mysql_error());
$handle = fopen("test.csv", "r");
// connect to mysql and select database or exit
mysql_select_db("db", $connect);
// loop content of csv file, using comma as delimiter
while (($data = fgetcsv($handle, 1000, ",")) !== false) {
$Product_ID = $data[0];
$Model = $data[1];
// entry insert
$query = "INSERT into products_test (products_id, products_model) VALUES '$Product_ID', $Model";
mysql_query($query);
if (mysql_affected_rows() <= 0) {
// no rows where affected by update query
}
} else {
// entry doesn't exist continue or insert...
}
mysql_free_result($result);
}
fclose($handle);
mysql_close($connect);
?>
Check your code.. The
} else {
// entry doesn't exist continue or insert...
}
Has no effect as there is no IF started for that. The one
if (mysql_affected_rows() <= 0) {
// no rows where affected by update query
}
Is already closed before 'Else ' statement. I could not get in to your query but this is what I got in first look
while (($data = fgetcsv($handle, 10000, "|")) !== false) {
$Product_ID = $data[0];
$Model = $data[1];
$HighPic = $data[2];
$ManuId = $data[3];
$parent_id = $data[7];
$Image = $data[13];
$Price = $data[14];
$Supplier = $data[15];
$Stock = $data[17];
// entry insert
$query = "INSERT into products_test (products_id, products_model, products_image, manufacturers_id, products_parent_id, icecat_manfimg, products_price, icecatcode, products_quantity) VALUES ($Product_ID, $Model, $HighPic, $ManuId, $parent_id, $Image, $Price, $Supplier, $Stock)" ;
mysql_query($query);
}
mysql_free_result($result);
fclose($handle);
mysql_close($connect);
?>