-1

Background:

I have a database table regarding various products. This database table is called product. The columns are set as id | group_id | model | description | price | .

id = the product id.
group_id = identifies the group that this product belongs too. 
model = product model 
description = Description
price = Price

From this table I generate a dynamic table based on the group_id of table product.

      <table>
<tr>
    <th>Model</th>
    <th>Description</th>
    <th>Price</th>
    <th>QTY</th>
</tr>  
 <?php        
   $conn = mysqli_connect("localhost", "root", "root", "test");
    // Check connection
    if ($conn->connect_error) {
    die("Connection failed: " . $conn->connect_error);
    }
  $sql ="SELECT * FROM product WHERE group_id = 2";
  $result = $conn->query($sql);
  while($row = $result->fetch_assoc()) :

 ?>      
     <tr>
    <td><?php echo $row['model']; ?></td>
    <td><?php echo $row['description']; ?></td>
    <td>R <?php echo $row['price']; ?></td>
    <td><input type="number" name = "<?php echo $row['id']?>" value = 0></td>

    </tr>
 <?php endwhile; ?>   


  </table>
   <div class="input-group">
  <button type="submit" class="btn" name="save">Save and Return</button>
  </div>
  </form>

This works well. Once this table is generated it allows the user to edit the quantity of each product that would fall under that group id, upon submit using POST, the information is sent to config_824.php

Please see code below for this file.

    <?php
session_start();
include ('customer_details_config.php');
$quote_id = $_SESSION['quote_id'];
$salesman_id = $_SESSION['salesman_id'];


$db = mysqli_connect('localhost', 'root', 'root', 'test');

 if (isset($_POST['save_pan_han'])){
    unset($_POST['save_pan_han']);
    foreach($_POST as $key => $value):
    $test_query = "SELECT * FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id";
    $result = mysqli_query($db, $test_query);
    $item = mysqli_fetch_assoc($result) or die (mysqli_error($db));


    if($item['quote_id'] == $quote_id &&
    $item['prod_id'] == $key &&
    $item['rep_id'] == $salesman_id){


           $update_query = "UPDATE quote_items SET
                    qty = $value

                    WHERE 

                    quote_id = $quote_id
                    AND prod_id = $key
                    AND rep_id = $salesman_id
                    ";
                    mysqli_query($db,$update_query) or die (mysqli_error($db));


        }else{
            $query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)" ;
        mysqli_query($db,$query) or die (mysqli_error($db));

        }
    endforeach;
}
?>

$quote_id is set with $_SESSION['quote_id'] and $salesman_id is set with $_SESSION['salesman_id'] when the user logs in.

quote items table has columns called id, quote_id, prod_id, rep_id, qty

CREATE TABLE `project`.`quote_items` ( `id` INT(10) NOT NULL AUTO_INCREMENT , `quote_id` INT(10) NOT NULL , `prod_id` INT(10) NOT NULL , `rep_id` INT(10) NOT NULL , `qty` INT(10) NOT NULL , PRIMARY KEY (`id`)) ENGINE = InnoDB;

As per the code above, I am trying to insert the data into a database table called quote_items, if I insert test data into the database, the UPDATE query runs fine.

The problem:

The issue is that if it checks and the row is not in the database, the INSERT query does not work. Nor do I see any errors despite error showing = TRUE.

I will use the following example: I have six rows of test data in the database. The dynamic table allows for 8 values to be set and sent to the database. So say the first two values are already in the database and would comply with UPDATE query. Value 3 and 4 has not yet been inserted and would fall under INSERT query. Value 5, 6, 7 and 8 again fall under the Update query.

If I run the code. Only row 1 and 2 would be updated. Row 3 and 4 would not be inserted and row 5, 6, 7, 8 would not be updated.

What I have tried:

Stackoverflow using mysqli_autocommit($db,FALSE);

Copy the query and insert into database via SQL in phpMyAdmin, if I remove the variables from the query it works fine on INSERT.

As you can see in the code above, I have an unset($var) as I noticed when I echo the array that the array included the table name. This is a string. If I try inserting a string this would cause issues obviously and I thougt this would resolve the issue.

This was sadly not the case.

Testing by removing the if and elseif and only using insert as recommended in a comment below:

<?php

    include ('customer_details_config.php');
    $quote_id = $_SESSION['quote_id'];
    $salesman_id = $_SESSION['salesman_id']; 


    $db = mysqli_connect('localhost', 'root', 'root', 'test');

    if (isset($_POST['save_pan_han'])):
        foreach($_POST as $key => $value): 
        $test_query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)";
            $result = mysqli_query($db, $test_query) or die (mysqli_error($db));

    /* 
    $item = mysqli_fetch_assoc($result) ;

     if ($item['quote_id'] == $quote_id &&
            $item['prod_id'] == $key &&
            $item['rep_id'] == $salesman_id
           ){
            $update_query = "UPDATE quote_items SET
            qty = $value

            WHERE 

            quote_id = $quote_id
            AND prod_id = $key
            AND rep_id = $salesman_id
            ";
            mysqli_query($db,$update_query) or die (mysqli_error($db));

        }else{ 
            $query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)" ;
            mysqli_query($db,$query) or die (mysqli_error($db));
        } 

       */
  endforeach;
endif;


?>
WWessels
  • 27
  • 6

3 Answers3

1

Is there a reason you are adding '' to the column names when you are inserting? When you are fdoing UPDATE you do not do that.

Replace this:

"INSERT INTO quote_items ('quote_id', 'prod_id', 'rep_id', 'qty') VALUES ($quote_id, $key, $salesman_id, $value)"

With:

"INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) VALUES ($quote_id, $key, $salesman_id, $value)"

Or maybe you wanted to use this: `

"INSERT INTO quote_items (`quote_id`, `prod_id`, `rep_id`, `qty`) VALUES ($quote_id, $key, $salesman_id, $value)"

Check this DEMO

VBoka
  • 8,995
  • 3
  • 16
  • 24
  • Thank you, I have edited my code accordingly as well as on this post. I can confirm that this, did not resolve the issue. But I understand why you made the suggestion. I have however also looked at the demo and I do not get the same error as you do. If I at least got errors that would help. – WWessels Nov 25 '19 at 11:18
  • I understand. Please note that you can "vote up" all the helpful answers and then at the end you can accept one that helped you the most or in other words it is correct answer. – VBoka Nov 25 '19 at 11:27
  • @WWessels please cab you explain when will this be true : $item['quote_id'] != $quote_id && $item['prod_id'] != $key && $item['rep_id'] != $salesman_id – VBoka Nov 25 '19 at 11:35
  • with the update query, I use the conditions to test that a row that matches in the table does exist, if so then that row should be updated. With the insert query, I test to confirm that if the row does not exist, then the row should not be inserted. So in short make sure there is no row WHERE quote_id IS NOT $quote_id AND prod_id IS NOT $key AND rep_id IS NOT $salesman_id, if TRUE then insert new row. Does that help in any way... – WWessels Nov 25 '19 at 11:49
  • I have even gone as far as removing the elseif and making it else, taking out the conditions of the else if and when the if is not TRUE to insert into the database, this dit not work either. – WWessels Nov 25 '19 at 11:51
  • @WWessels please do check if you have the same code here in your question and in your working enviroment because here you still have one ' that does not belong: '$salesman_id – VBoka Nov 25 '19 at 11:59
  • Also, can you, just for test, leave only insert code ? Without any `if` and `alse` and without UPDATE statement ? – VBoka Nov 25 '19 at 12:01
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/203026/discussion-between-wwessels-and-vboka). – WWessels Nov 25 '19 at 12:08
  • @WWessels well I believe that I have , with my answers, succesfuly detected the first problem. It would be nice ti accpet this answer. Also I suggest that for your new problem, you open a new question and try to be clear about the proble there... – VBoka Nov 26 '19 at 12:41
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Dec 01 '19 at 22:13
0

Add single quotes around the values in your insert statement like you did in your update statement so they are properly recognized as strings in SQL.

Except for the fields that aren't strings of course, but since you didn't post your create table script that's impossible to tell from your code.

Also using string concatenation to build SQL statements is a horrible security issue and you absolutely must use PDO and prepared statements!

Longoon12000
  • 774
  • 3
  • 13
  • Thank you for your assistance. I have added the missing code for you. I have also added the single quotes, and tested again. The values are integers and so is the field type in the database, so this should not be an issue. I agree with the importance of prepared statements, this is merely a testing prototype being constructed and not yet intended to go life. I will look at validation and prepared statements if I have enough interest in the project. – WWessels Nov 25 '19 at 11:00
-1

I finally got the result I wanted. Well almost.

    $db = mysqli_connect('localhost', 'root', 'root', 'test');

 if (isset($_POST['save_pan_han'])){
    unset($_POST['save_pan_han']);
    foreach($_POST as $key => $value):

     $query = "INSERT INTO quote_items (quote_id, prod_id, rep_id, qty) SELECT $quote_id, $key, $salesman_id, $value WHERE NOT EXISTS (SELECT quote_id, prod_id, rep_id, qty FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id)";
        mysqli_query($db,$query) or die (mysqli_error($db));

     endforeach;

     foreach($_POST as $key => $value):

     $test_query = "SELECT * FROM quote_items WHERE quote_id = $quote_id AND prod_id = $key AND rep_id = $salesman_id";
    $result = mysqli_query($db, $test_query);
    $item = mysqli_fetch_assoc($result) or die (mysqli_error($db));

    if($item['quote_id'] == $quote_id &&
    $item['prod_id'] == $key &&
    $item['rep_id'] == $salesman_id){


           $update_query = "UPDATE quote_items SET
                    qty = $value

                    WHERE 

                    quote_id = $quote_id
                    AND prod_id = $key
                    AND rep_id = $salesman_id
                    ";
                    mysqli_query($db,$update_query) or die (mysqli_error($db));

        }


    endforeach;

}
?>

The only issue is that this now also would insert rows where qty = 0

I will just include a DROP query. If anyone has a better suggestion, please add. I know I am making too many calls to the database for this to be the best solution.

WWessels
  • 27
  • 6
  • **Warning:** You are wide open to [SQL Injections](https://php.net/manual/en/security.database.sql-injection.php) and should use parameterized **prepared statements** instead of manually building your queries. They are provided by [PDO](https://php.net/manual/pdo.prepared-statements.php) or by [MySQLi](https://php.net/manual/mysqli.quickstart.prepared-statements.php). Never trust any kind of input! Even when your queries are executed only by trusted users, [you are still in risk of corrupting your data](http://bobby-tables.com/). [Escaping is not enough!](https://stackoverflow.com/q/5741187) – Dharman Dec 01 '19 at 22:11