PHP PDO multiple insert doesnt work - php

I follow the solution from this example: PDO Prepared Inserts multiple rows in single query
, i dont have any error but insert doesnt work. This is the code:
$pdo = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'username', 'password');
$fields = array('field1', 'field2', 'field3', 'field4');
$pdo->beginTransaction();
$insert_values = array();
foreach ($dataForInsert as $key => $value) {
$question_marks[] = '(' . $this->placeholders('?', sizeof($value)) . ')';
$insert_values = array_merge($insert_values, array_values($value));
}
$sql = "INSERT INTO table (" . implode(",", $fields ) . ") VALUES " . implode(',', $question_marks);
$stmt = $pdo->prepare($sql);
try {
$stmt->execute($insert_values);
} catch (PDOException $e){
echo $e->getMessage();
}
where i am making mistake?

Related

php inserts only last array record into sql

I have working code, which inserts data into csv file. Here is a part of it:
if (isset($_POST['array'])) {
foreach ($_POST['array'] as $loop) {
$txt = $txt . $loop['name'] . ";" . $loop['email'];
$txt .="\n";
}
}
Instead of csv, i would like it to insert data into mysql database, so i have simply changed the code to:
if (isset($_POST['array'])) {
foreach ($_POST['array'] as $loop) {
$sql = "insert into persons (Name, Email)
values ('" . $loop['name'] . "', '" . $loop['email'] . "')";
}
}
Only the last record is saved into the persons table. There are no errors, but all the previous records except last are not inserted. Why?
Better way is only one time create insert
if (isset($_POST['array'])) {
$values = [];
$sql = "insert into persons (Name, Email) values ";
foreach ($_POST['array'] as $loop) {
$values[] = "('" . $conn->real_escape_string($loop['name']) . "', '" . $conn->real_escape_string($loop['email']) . "')";
}
if (!empty($values)) {
$conn->query($sql . implode(', ', $values));
}
}
The reason why it doesn't work is because you never execute your SQL query anywhere.
To execute the query you should first prepare the statement and then bind the params and execute.
// Your connection to DB
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$mysqli = new mysqli('localhost', 'username', 'password', 'dbname');
$mysqli->set_charset('utf8mb4'); // always set the charset
if (isset($_POST['array'])) {
$stmt = $mysqli->prepare('INSERT INTO persons (Name, Email) VALUES (?,?)');
foreach ($_POST['array'] as $loop) {
$stmt->bind_param('ss', $loop['name'], $loop['email']);
$stmt->execute();
}
}
Please execute query inside the loop as given below
...
$conn = mysqli_connect($servername, $username, $password, $dbname);
...
if (isset($_POST['array'])) {
foreach ($_POST['array'] as $loop) {
$sql = "insert into persons (Name, Email)
values ('" . $loop['name'] . "', '" . $loop['email'] . "')";
$conn->query($sql);// Query should execute inside loop
}
}
I had the same issue inserting JSON arrays into MySQL and fixed it by putting the mysqli_stmt->execute() function inside the foreach
// loop through the array
foreach ($data as $row) {
echo "Data has been Uploaded successfully <br>";
// get the project details
$id = $row['id'];
$name = $row['name'];
$togglCid = $row['cid'];
// execute insert query
mysqli_stmt_execute($sql);
}
This means it executes the code after each loop
If you want to execute the query outside the loop
Try using as following
if (isset($_POST['array'])) {
$sql="";
foreach ($_POST['array'] as $loop) {
$sql .= "insert into persons (Name, Email)
values ('" . $loop['name'] . "', '" . $loop['email'] . "');\n";
}
}

HY:093 Invalid parameter number: parameter was not defined

I dont understand why I'm getting this error
if (isset($_POST['submit'])) {
require "../config.php";
require "../common.php";
try {
$connection = new PDO($dsn, $username, $password, $options);
$new_user = array(
"Nom" => $_POST['Nom'],
"EmailID" => $_POST['EmailID'],
"localité" => $_POST['localité']
);
$sql = sprintf(
"INSERT INTO %s (%s) values (%s)",
"memfis",
implode(", ", array_keys($new_user)),
":" . implode(", :", array_keys($new_user))
);
$statement = $connection->prepare($sql);
$statement->execute($new_user);
} catch(PDOException $error) {
echo $sql . "<br>" . $error->getMessage();
}
}
?>
<?php require "templates/header.php"; ?>
<?php if (isset($_POST['submit']) && $statement) { ?>
<blockquote><?php echo $_POST['name']; ?> successfully added.</blockquote>
<?php } ?>
Should Only had added the user and display "'Nom' successfully added" and Nom should and the other fields should have been added.
Why so complex on the query build? It is typically better to be readable and maintainable than fancy.
$sql = sprintf(
"INSERT INTO %s (%s) values (%s)",
"memfis",
implode(", ", array_keys($new_user)),
":" . implode(", :", array_keys($new_user))
);
Maybe try changing that to something like:
$table = "memfis";
$columnNames = implode(", ", array_keys($new_user));
$columnPlaceholders = ":" . implode(", :", array_keys($new_user));
$sql = "INSERT INTO $table ($columnNames) VALUES ($columnPlaceholders)";
$stmt = $pdo->prepare($sql);
And then because your query is going to have things like :Nom as placeholders, you need to use bindParam().
foreach (array_keys($new_user) as $key) {
$placeholder = ":" . $key;
$stmt->bindParam($placeholder, $new_user[$key]);
}
$stmt->execute();
I know that code is longer, but it is easier to read and maintain IMHO than what you have.

Getting an error 'Error: INSERT INTO `call`.`logs` (id, hashkey, ) VALUES (, XXX, )'

I have been retrieving call logs from a cdr and dumping them into a database in MySQL. Of late the database crashes and the was giving me duplicates and junk characters so i modified to the below code.
modified code
$file1 = file_get_contents('file:///C:/Users/thy/Desktop/2011_0419_1531_v3.12R/cdr/'.$newname, FILE_USE_INCLUDE_PATH);
$arr1 = explode("\n", $file1);
foreach ($arr1 as $key => $value) {
$colArray = [];
$colArray['id'] = null;
$colArray['hashkey'] = md5(uniqid(rand(), true));
$split = explode(";", $value);
foreach ($split as $key => $val) {
# code...
$arr = (explode('=', $val));
$field = 'ch';
$item = '0';
$field = $arr[0];
$item = $arr[1];
$item = str_replace(str_split(')(\/'), '', $item);
$colArray[$field] = $item;
}
$columns = implode(', ', array_keys($colArray));
$values = implode(', ', $colArray);
$sql = "INSERT INTO `call`.`logs` (" . $columns . ") VALUES (" . $values . ")";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
}
the above code keeps giving me errors
Error: INSERT INTO call.logs (id, hashkey, ) VALUES (,
797d8782a433b30e196fafc0ce01d09b, )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 ') VALUES (,
797d8782a433b30e196fafc0ce01d09b, )' at line 1
Original code is below (the one i modified it from)
$file1 = file_get_contents('file:///C:/Users/thy/Desktop/2011_0419_1531_v3.12R/cdr/'.$newname, FILE_USE_INCLUDE_PATH);
$arr1 = explode("\n", $file1);
$data1 = array();
foreach ($arr1 as $key => $value) {
$split = explode(";", $value);
$keys = md5(uniqid(rand(), true));
//insert key to identify call.
$sql = "INSERT INTO `call`.`logs` (`id`, `hashkey`) VALUES (NULL, '{$keys}')";
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
foreach ($split as $key => $val) {
# code...
$arr=(explode('=', $val));
$field='ch';
$item='0';
$field=$arr[0];
$item=$arr[1];
echo $field . " --";
echo "<br/>";
echo $item;
//sql
$sql = "UPDATE logs SET {$field}='{$item}' WHERE hashkey='{$keys}'";
if ($conn->query($sql) === TRUE) {
echo "Record updated successfully";
} else {
echo "Error updating record: " . $conn->error;
}
echo "done";
//$conn->close();
} echo "<br/>";
}
?>
<?php
I think the problem is with the generated/devised INSERt statement
INSERT INTO call.logs (" . $columns . ") VALUES (" . $values . ")";
There is an extra comma getting appended without column name?
If id is an autoincremental field. Try this:
INSERT INTO call.logs (id, hashkey) VALUES (default, '797d8782a433b30e196fafc0ce01d09b')

Json data getting read but not inserting into mysql using php

Im trying to insert json data using php into mysql,
I get success msg, but no records are inserted.
My json data is :
jsondata.json:
{"users": { "bert":6.44, "earnie":0.25, "bigbird":34.45 }}
My php code:
<?php
//First: read data
$fo=fopen("data.json","r");
$fr=fread($fo,filesize("data.json"));
$array=json_decode($fr,true);
//Second: create $values
$rows = array();
foreach ($array['users'] as $key => $value)
$rows[] = "('" . $key . "', '" . $value . "')";
$values = implode(",", $rows);
//To display all values from JSON file
echo '<pre>';print_r($array);
//Save to DB
$hostname = 'localhost';
$username = 'root';
$password = '';
try
{
$dbh = new PDO("mysql:host=$hostname;dbname=nodejs", $username, $password);
echo 'Connected to database<br />';
//$count = $dbh->exec("INSERT INTO USERSAMOUNTS(USERNAME, AMOUNT) VALUES " . $values) or die(print_r($dbh->errorInfo(), true));
$count = $dbh->exec("INSERT INTO json(firstName) VALUES " . $values) or die(print_r($dbh->errorInfo(), true));
echo $count;// echo the number of affected rows
$dbh = null;// close the database connection
echo 'Success<br />';
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
I believe the problem could be the order in which the actions are performed.
<?php
//First: read data
$fo = fopen("jsondata.json", "r");
$fr = fread($fo, filesize("jsondata.json"));
$array = json_decode($fr, true);
//Second: create $values
$rows = array();
foreach ($array['users'] as $key => $value)
$rows[] = "('" . $key . "', '" . $value . "')";
$values = implode(",", $rows);
//Third: display
echo '<pre>';
print_r($array);
//Fourth: save to db
$hostname = 'localhost';
$username = 'root';
$password = '';
try {
$dbh = new PDO("mysql:host=$hostname;dbname=nodejs", $username, $password);
echo 'Connected to database<br />'; // echo a message saying we have connected
$count = $dbh->exec("INSERT INTO USERAMOUNTS(USERNAME, AMOUNT) VALUES " . $values);
echo $count; // echo the number of affected rows
$dbh = null; // close the database connection
echo 'Success<br />';
} catch (PDOException $e) {
echo $e->getMessage();
}
?>
Enables or disables emulation of prepared statements. Some drivers do not support native prepared statements or have limited support for them for more info please check - http://php.net/manual/en/pdo.setattribute.php
$dbh = new PDO("mysql:host=$hostname;dbname=nodejs", $username, $password);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$count = $dbh->exec("INSERT INTO USERAMOUNTS(USERNAME, AMOUNT) VALUES " . $values);
Hope this help.
The issue is with how your are trying to insert data. I'm surprised you're not getting an error.
You should use a prepared statement. See the following... https://stackoverflow.com/a/4629088/2033178
Some things are funky here.
At first it looks like you're expecting the data to come magically from $data (unless that is passed somewhere?)
$array = json_decode($data, true);
$rows = array();
foreach($array['users'] as $key => $value)
$rows[] = "('" . $key . "', '" . $value . "')";
$values = implode(",", $rows);
And then it looks like you're opening a file and parsing the JSON (but not doing the above magic with $rows[])
$fo=fopen("jsondata.json","r");
$fr=fread($fo,filesize("jsondata.json"));
$array=json_decode($fr,true);
Why not insert on the for each loop?
$fo=fopen("jsondata.json","r");
$fr=fread($fo,filesize("jsondata.json"));
$array=json_decode($fr,true);
$count = 0;
$dbh = new PDO("mysql:host=$hostname;dbname=nodejs", $username, $password);
try {
foreach($array['users'] as $key => $value)
$count = $count + $dbh->exec("INSERT INTO USERAMOUNTS(USERNAME, AMOUNT) VALUES " . $key . " " . $value . ")";
} catch ...

Bind parameters dynamically to a mysqli statement

I am trying to build a dynamic prepared statement but I am stuck at the bind_param part. I tried to read other answers referring to call_user_func_array but I couldn't figure out how to adapt it here:
//connecting
$connection = new mysqli(DB_SERVER, DB_USER, DB_PASSWORD, DB_NAME);
//info submitted through a form
$values_columns = array(
"column_one" => "value_one", //value_one will be replaced by $_POST['value_one']
"column_two" => "value_two", //value_two will be replaced by $_POST['value_two']
"column_three" => "value_three" //value_three will be replaced by $_POST['value_three']
);
$value_type = implode('', array('s', 's', 's'));
//preparing and binding my query dinamically
function prepare_bind($table_name, $values_columns, $value_type) {
global $connection;
$columns_string = "";
$question_marks = "";
$flag = 0;
$count = count($values_columns);
foreach ($values_columns as $column => $value) {
$flag++;
// building the prepare
if ($flag == $count) {
$columns_string .= $column;
$question_marks .= "?";
} else {
$columns_string .= $column . ", ";
$question_marks .= "?, ";
}
}
$sql = $connection->prepare('INSERT INTO ' . $table_name . ' (' . $columns_string . ') VALUES (' . $question_marks . ')');
$sql->bind_param($value_type, /*I am stuck here while trying to add the values*/);
}
Is there any way to get out of this situation. It is the first time I am using this approach and I don't know if I got it right. Thank you very much.
Easiest solution to generating the placeholders:
function placeholderMarks($count) {
return join(', ', array_fill(0, $count, '?'));
}
Insert the result of this function into the query with placeholderMarks(count($values_columns))

Categories