-1

Json to MySQL when ran it imports into the database fine. When i run the SQL Query manually it runs without an error.

When am running it through the code, its returning back with a error in my SQL syntax near line 1.

I have removed the magic quotes, still errors. Can someone shine some light on this before i chuck in the towl.

I understand magic quotes are deprecated, and i thought this was causing the error, but these have been removed.

<?php
/**
 * Created by PhpStorm.
 * User: dave
 * Date: 14/11/2018
 * Time: 15:26
 */

$connect = mysqli_connect("localhost", "root", "password", "clients");
$query = '';
$table_data = '';
$filename = "test.json";

$data = file_get_contents($filename);
$array = json_decode($data, true);

foreach($array as $set)
{
    $tblName = $set['tableName'];
    echo $tblName ;
    if(sizeof($set['rows']) > 0) {
        $query = '';
        $colList = array();
        $valList = array();
        //  Get list of column names
        foreach($set['rows'][1] as $colname => $dataval) {
          // $colList[] = "`".$colname."`";
           $colList[] = $colname;
        }
        $query .= "INSERT INTO ".$tblName." \n";
        $query .= "(".implode(", ",$colList).")\nVALUES\n";
        //  Go through the rows for this table.
        foreach($set['rows'] as $idx => $row) {
            $colDataA = array();
            //  Get the data values for this row.
            foreach($row as $colName => $colData) {
                $colDataA[] = "'".$colData."'";
            }
            $valList[] = "(".implode(",",$colDataA).")";
        }
        //  Add values to the query.
        $query .= implode(",\n",$valList)."\n";
        echo "<p>Insert query:<pre>$query</pre></p>";
        $results = mysqli_query($connect, $query);

 //       if ($connect->query($results) === TRUE) {
 //           echo "New record created successfully";
 //       } else {
  //          echo $results . "<br>" . $query . "<br>" ;
 //            echo "error" .$connect->error ;
 //       }

        echo "<h1>".mysqli_num_rows($connect)." Rows appeded in $tblName</h1>";
    } else {
        echo "<p>No rows to insert for $tblName</p>";
    }
}

Json File:

[
    {
      "tableName":"contacts",
      "rows":[
        {
          "First_Name": "Dave",
          "Last_Name": "Frank",
          "Company": "Company1",
          "Business_Phone": "0115 999999",
          "Email_Address": "zvv@zz.com"
        },
        {
          "First_Name": "Dave",
          "Last_Name": "Blogs",
          "Company": "Company2",
          "Business_Phone": "0115 888888",
          "Email_Address": "zvv@zz.com"
        },
        {
          "First_Name": "David",
          "Last_Name": "frank",
          "Company": "Company3",
          "Business_Phone": "0115 777777",
          "Email_Address": "zvv@zz.com"
        }
      ]
    },
    {
      "tableName":"contacts_old",
      "rows":[
        {
          "First_Name": "Dave",
          "Last_Name": "Frank",
          "Company": "Company1",
          "Business_Phone": "0115 999999",
          "Email_Address": "zvv@zz.com"
        },
        {
          "First_Name": "Dave",
          "Last_Name": "Blogs",
          "Company": "Company2",
          "Business_Phone": "0115 888888",
          "Email_Address": "zvv@zz.com"
        },
        {
          "First_Name": "David",
          "Last_Name": "frank",
          "Company": "Company3",
          "Business_Phone": "0115 777777",
          "Email_Address": "zvv@zz.com"
        }
      ]
    }
]

Here is the Echo as per request:

contacts

Insert query:

INSERT INTO contacts 
(First_Name, Last_Name, Company, Business_Phone, Email_Address)
VALUES
('Dave','Frank','Company1','0115 999999','zvv@zz.com'),
('Dave','Blogs','Company2','0115 888888','zvv@zz.com'),
('David','frank','Company3','0115 777777','zvv@zz.com')

Error: 1
INSERT INTO contacts (First_Name, Last_Name, Company, Business_Phone, Email_Address) VALUES ('Dave','Frank','Company1','0115 999999','zvv@zz.com'), ('Dave','Blogs','Company2','0115 888888','zvv@zz.com'), ('David','frank','Company3','0115 777777','zvv@zz.com')
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1' at line 1contacts_old

Insert query:

INSERT INTO contacts_old 
(First_Name, Last_Name, Company, Business_Phone, Email_Address)
VALUES
('Dave','Frank','Company1','0115 999999','zvv@zz.com'),
('Dave','Blogs','Company2','0115 888888','zvv@zz.com'),
('David','frank','Company3','0115 777777','zvv@zz.com')

Error: 1
INSERT INTO contacts_old (First_Name, Last_Name, Company, Business_Phone, Email_Address) VALUES ('Dave','Frank','Company1','0115 999999','zvv@zz.com'), ('Dave','Blogs','Company2','0115 888888','zvv@zz.com'), ('David','frank','Company3','0115 777777','zvv@zz.com')
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '1' at line 1

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in

miken32
  • 42,008
  • 16
  • 111
  • 154
Dave Hamilton
  • 675
  • 1
  • 12
  • 23
  • As you echo `$query` can you show what this produces. – Nigel Ren Nov 14 '18 at 19:32
  • edited post with data – Dave Hamilton Nov 14 '18 at 19:35
  • If you copy, paste and run the query in PhpMyAdmin do you get the same error? – Edwin Krause Nov 14 '18 at 19:38
  • 2
    Your executing the query twice - `$results = mysqli_query($connect, $query);` and then with the result `if ($connect->query($results) === TRUE) {` – Nigel Ren Nov 14 '18 at 19:39
  • Running it through PhpMyAdmin returns success and no errors. To add, the data actually does insert into the MySQL Database when run from the code, but it errors for some reason, An because its erroring i crnt add any handlers like mysqli_num_rows – Dave Hamilton Nov 14 '18 at 19:39
  • @NigelRen its not that, all be it, it is there twice, but for debugging. Still get Error1 with it included. – Dave Hamilton Nov 14 '18 at 19:41
  • But `query` takes the SQL string (`$query`) and your passing in `$results`. – Nigel Ren Nov 14 '18 at 19:43
  • 1
    And `$results` will be coerced into being a `1` because of PHP's loose typing. That said, you're doing this the wrong way, and everything's going to fall apart as soon as you hit John O'Malley. – miken32 Nov 14 '18 at 19:46
  • Removing the code makes no difference, leaving the one line $results = mysqli_query etc etc as i cannot run mysqli_num_rows($results) as its returning false because of a sql error – Dave Hamilton Nov 14 '18 at 19:46
  • @miken32 why am i doing it wrong? are you not able to provide any info or any guidance?? – Dave Hamilton Nov 14 '18 at 19:51
  • 1
    I'm working up an answer for you now. Short version: prepared statements. – miken32 Nov 14 '18 at 19:52

1 Answers1

2

So as Nigel pointed out, your original problem was caused by passing a result set to query() instead of a string. I expect this question will be closed as off-topic due to typo, but there are a number of problems and inefficiencies in your code I wanted to point out before that happens.

Most importantly, your lack of prepared statements and data sanitization means that your query will fall apart as soon as an apostrophe shows up. I'm rusty on mysqli, so I've used PDO in this code here, because I can do it off the top of my head. It's a more modern interface anyway, and far less verbose. You can read more about prepared statements in both PDO and mysqli, but the important thing to remember is that you prepare your statement, using ? as a placeholder for values you're going to insert. Then, you execute the statement, passing the values in. The database takes care of escaping any nasty values, and it's a lot less overhead than rebuilding an entire query on every iteration of the loop.

You should also be looking to use PHP's built-in functions like array_keys, array_values, or array_columns to extract data, rather than resorting to foreach loops.

<?php
$connect = new PDO("mysql:host=localhost;dbname=clients", "root", "password");
$filename = "test.json";

$data = file_get_contents($filename);
$array = json_decode($data, true);

foreach($array as $set)
{
    $tblName = $set['tableName'];
    if(count($set['rows']) > 0) { /* typical to use count() for measuring array size */
        //  Get list of column names
        $colList = array_keys($set["rows"][0]); /* no loop needed */
        $query = "INSERT INTO `$tblName` \n";
        $query .= "(" . implode(", ", $colList) . ")\nVALUES\n";
        $placeholders = implode(",", array_fill(0, count($colList), "?"));
        $query .= "($placeholders)"; /* you should have INSERT INTO xxx (yyy, zzz) VALUES (?, ?) */
        $stmt = $connect->prepare($query);
        if (!$stmt) {
            echo "Prepare error: $query<br/>" . $connect->errorInfo()[2];
            continue; /* give up, go to next record set */
        }
        //  Go through the rows for this table.
        foreach($set['rows'] as $row) {
            $result = $stmt->execute($row); /* hey you can just pass the array directly! */
            if ($result === TRUE) {
                echo "New record created successfully";
            } else {
                echo "Execute error: $stmt->queryString<br/>" . $stmt->errorInfo()[2];
            }
        }
    } else {
        echo "<p>No rows to insert for $tblName</p>";
    }
}
miken32
  • 42,008
  • 16
  • 111
  • 154
  • 1
    superb. Although for completeness I would have added that one should never get an application to log into the database as root, even for testing purposes. – ADyson Nov 14 '18 at 22:36
  • Thanks Mike, If i am using Multiple Nodes as in the example, How am i to extract the values without a foreach? I have been trying without getting into another foreach, but i only turn the values the one node. I can accomplish this simply with a foreach, but am trying to take onboard your info. I was not worried too much about data sanitizing as this will become a CRUD, and ill be doing the sanitizing on the other end. – Dave Hamilton Nov 15 '18 at 09:47
  • I was getting confused with how you where passing the values across. I never use PDO. After some reading i was able to get this to work. I needed the values to pass across in the foreach. So $row = array_values($row); Just before the execute Thanks – Dave Hamilton Nov 15 '18 at 11:44
  • Right I forgot you were getting an associative array from your JSON, sorry about that. `array_values()` is exactly the tool to use. – miken32 Nov 15 '18 at 14:09
  • And yes, a loop is still the easiest way to go through the different tables and their rows. Nothing wrong with a `foreach`, just best to avoid them when you’re looking at dozens of iterations and there are perfectly good functions to use instead! – miken32 Nov 15 '18 at 14:14