Using PDO in PHP, when having to insert multiple rows into a table at once, I've used sql that looks something like this:
INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce');
As you can see I'm inserting three rows with one statement. The reason I do this is that I believe it is more efficient than executing three distinct statements to insert the rows.
So my question is this: how do I do this in PHP if I want to be able to bind my values to a statement like I do in single statement:
$query= ("INSERT INTO table (firstName, lastName) VALUE (:firstName, :lastName)", array = (
"firstname"=>$firstName,
"lastName"=>$lastName));
So my question is: Is there any way to bind in a multi-insert statement? Something like:
INSERT INTO table (firstName, lastName) VALUES((:firstName, :lastName),(:firstName, :lastName));
In theory, it might sound like a single statement is more efficient because you avoid making multiple calls to MySQL server, but the reality is that this a micro-optimization and you are overcomplicating your code for barely any benefit.
The cool thing about prepared statements is that it is prepared once and can be executed multiple times. This already saves you parsing the SQL statement multiple times. Simply prepare a statement outside of a loop and then execute it inside a loop.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO table (firstName, lastName) VALUES(?,?)');
foreach ($names as $name) {
$stmt->execute($name);
}
If you wrap the whole thing in a transaction as Your Common Sense suggested in the comments then there is no noticeable difference in performance compared to one big statement.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO people (firstName, lastName) VALUES(?,?)');
$pdo->beginTransaction();
foreach ($names as $name) {
$stmt->execute($name);
}
$pdo->commit();
Just create your query text wtih ? placeholders as:
INSERT INTO table (firstName, lastName) VALUES (?, ?),(?, ?),(?, ?)
And execute it. Sample code can be:
$data = ['Joe', 'Smith','Fred','Sampson','Lisa','Pearce'];
$placeholders = ['(?, ?)', '(?, ?)', '(?, ?)']; // but you should define this data according to your data
$query = 'INSERT INTO table (firstName, lastName) VALUES ' . implode(',', $placeholders);
$stmt = $dbh->prepare($query);
$stmt->execute($data);
Related
Using PDO in PHP, when having to insert multiple rows into a table at once, I've used sql that looks something like this:
INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce');
As you can see I'm inserting three rows with one statement. The reason I do this is that I believe it is more efficient than executing three distinct statements to insert the rows.
So my question is this: how do I do this in PHP if I want to be able to bind my values to a statement like I do in single statement:
$query= ("INSERT INTO table (firstName, lastName) VALUE (:firstName, :lastName)", array = (
"firstname"=>$firstName,
"lastName"=>$lastName));
So my question is: Is there any way to bind in a multi-insert statement? Something like:
INSERT INTO table (firstName, lastName) VALUES((:firstName, :lastName),(:firstName, :lastName));
In theory, it might sound like a single statement is more efficient because you avoid making multiple calls to MySQL server, but the reality is that this a micro-optimization and you are overcomplicating your code for barely any benefit.
The cool thing about prepared statements is that it is prepared once and can be executed multiple times. This already saves you parsing the SQL statement multiple times. Simply prepare a statement outside of a loop and then execute it inside a loop.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO table (firstName, lastName) VALUES(?,?)');
foreach ($names as $name) {
$stmt->execute($name);
}
If you wrap the whole thing in a transaction as Your Common Sense suggested in the comments then there is no noticeable difference in performance compared to one big statement.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO people (firstName, lastName) VALUES(?,?)');
$pdo->beginTransaction();
foreach ($names as $name) {
$stmt->execute($name);
}
$pdo->commit();
Just create your query text wtih ? placeholders as:
INSERT INTO table (firstName, lastName) VALUES (?, ?),(?, ?),(?, ?)
And execute it. Sample code can be:
$data = ['Joe', 'Smith','Fred','Sampson','Lisa','Pearce'];
$placeholders = ['(?, ?)', '(?, ?)', '(?, ?)']; // but you should define this data according to your data
$query = 'INSERT INTO table (firstName, lastName) VALUES ' . implode(',', $placeholders);
$stmt = $dbh->prepare($query);
$stmt->execute($data);
Using PDO in PHP, when having to insert multiple rows into a table at once, I've used sql that looks something like this:
INSERT INTO some_names (firstName, lastName) VALUES ('Joe', 'Smith'),('Fred','Sampson'),('Lisa','Pearce');
As you can see I'm inserting three rows with one statement. The reason I do this is that I believe it is more efficient than executing three distinct statements to insert the rows.
So my question is this: how do I do this in PHP if I want to be able to bind my values to a statement like I do in single statement:
$query= ("INSERT INTO table (firstName, lastName) VALUE (:firstName, :lastName)", array = (
"firstname"=>$firstName,
"lastName"=>$lastName));
So my question is: Is there any way to bind in a multi-insert statement? Something like:
INSERT INTO table (firstName, lastName) VALUES((:firstName, :lastName),(:firstName, :lastName));
In theory, it might sound like a single statement is more efficient because you avoid making multiple calls to MySQL server, but the reality is that this a micro-optimization and you are overcomplicating your code for barely any benefit.
The cool thing about prepared statements is that it is prepared once and can be executed multiple times. This already saves you parsing the SQL statement multiple times. Simply prepare a statement outside of a loop and then execute it inside a loop.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO table (firstName, lastName) VALUES(?,?)');
foreach ($names as $name) {
$stmt->execute($name);
}
If you wrap the whole thing in a transaction as Your Common Sense suggested in the comments then there is no noticeable difference in performance compared to one big statement.
$names = [['Joe', 'Smith'], ['Fred', 'Sampson'], ['Lisa', 'Pearce']];
$stmt = $pdo->prepare('INSERT INTO people (firstName, lastName) VALUES(?,?)');
$pdo->beginTransaction();
foreach ($names as $name) {
$stmt->execute($name);
}
$pdo->commit();
Just create your query text wtih ? placeholders as:
INSERT INTO table (firstName, lastName) VALUES (?, ?),(?, ?),(?, ?)
And execute it. Sample code can be:
$data = ['Joe', 'Smith','Fred','Sampson','Lisa','Pearce'];
$placeholders = ['(?, ?)', '(?, ?)', '(?, ?)']; // but you should define this data according to your data
$query = 'INSERT INTO table (firstName, lastName) VALUES ' . implode(',', $placeholders);
$stmt = $dbh->prepare($query);
$stmt->execute($data);
I am inserting data that has VARCHAR, TIMESTAMP and DECIMAL kinds using prepare.
The data is already in the format needed by mySQL.
My problem is this. Suppose I had only 2 items to insert. I would do like this:
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param("si", $_POST['name'], $_POST['age']);
My problem is the bind part. How do I do the bind when I have to insert 40 columns at once?
I can deal with the prepare part by doing this:
$sql = "INSERT INTO customers ($columns) VALUES ($values)";
$stmt = $mysqli->prepare($sql);
But the next line will result in a ridiculous long line, impossible to understand and very easy to go wrong.
$stmt->bind_param("ssssiidisisssiidiisssidiisidi", ....);
I don't see how I could build that in a loop for example.
How do I do that?
You can pass an array to the mysqli_stmt::bind_param() function as variable arguments with the ... syntax, introduced in PHP 5.6.
$params = ['name', 42];
$stmt = $mysqli->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->bind_param(str_repeat('s', count($params)), ...$params);
$stmt->execute();
You don't really need to set the data type individually for each column. You can treat them all as 's'.
I know you're asking about mysqli, but I'll just point out that this is easier with PDO:
$params = ['name', 42];
$stmt = $pdo->prepare("INSERT INTO myTable (name, age) VALUES (?, ?)");
$stmt->execute($params);
Following the tutorial here to save multiple entry in database i came up with this code
foreach($array as $value){
$stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)");
$stmt->bindParam(':name', $value['name']);
$stmt->bindParam(':value', $value['value']);
$stmt->execute();
}
foreach($array1 as $value){
$stmt = $dbh->prepare ("INSERT INTO user (firstname, surname) VALUES (:fname, :sname)");
$stmt -> bindParam(':fname', 'John');
$stmt -> bindParam(':sname', 'Smith');
$stmt -> execute();
}
I have something like this just different table and value but the code is the same. I want to ask why the second foreach didnt fire,it was not saved only the first foreach got fired and only the first set of data was saved.How to make it that they both get fired and saved.
Make sure you use the same keywords like you did for the first array
Replace:
VALUES (:f-name, :s-name)")
by
VALUES (:fname, :sname)")
because your stmt call fname and sname, but not s-name and f-name
i used this code
<?php
$conn = new PDO("mysql:host=localhost;dbname=CU4726629",'CU4726629','CU4726629');
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ("$_POST['username']","$_POST['moviename']","$_POST['ratings']")";
header('Location: reviews.php');
?>
but it keeps giving me this error
Parse error: syntax error, unexpected T_VARIABLE in
/home/4726629/public_html/check_login.php on line 5
Take this for an example:
<?php
// insert some data using a prepared statement
$stmt = $dbh->prepare("insert into test (name, value) values (:name, :value)");
// bind php variables to the named placeholders in the query
// they are both strings that will not be more than 64 chars long
$stmt->bindParam(':name', $name, PDO_PARAM_STR, 64);
$stmt->bindParam(':value', $value, PDO_PARAM_STR, 64);
// insert a record
$name = 'Foo';
$value = 'Bar';
$stmt->execute();
// and another
$name = 'Fu';
$value = 'Ba';
$stmt->execute();
// more if you like, but we're done
$stmt = null;
?>
You just wrote a string in your above code:
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ("$_POST['username']","$_POST['moviename']","$_POST['ratings']")";
Above answers are correct, you will need to concat the strings to form a valid sql query. you can echo your $sql variable to check what is to be executed and if is valid sql query or not. you might want to look in to escaping variables you will be using in your sql queries else your app will be vulnerable to sql injections attacks.
look in to
http://php.net/manual/en/pdo.quote.php
http://www.php.net/manual/en/pdo.prepare.php
Also you will need to query you prepared sql statement.
look in to http://www.php.net/manual/en/pdo.query.php
A couple of errors:
1) you have to concat the strings!
like this:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (".$_POST['username'].",".$_POST['moviename'].",".$_POST['ratings'].")";
2) you are not using the PDO at all:
after you create the "insert" string you must query the db itself, something like using
$conn->query($sql);
nb: it is pseudocode
3) the main problem is that this approach is wrong.
constructing the queries in this way lead to many security problems.
Eg: what if I put "moviename" as "; drop table review;" ??? It will destroy your db.
So my advice is to use prepared statement:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (?,?,?)";
$q = $conn->prepare($sql);
$fill_array = array($_POST['username'], $_POST['moviename'], $_POST['ratings']);
$q->execute($fill_array);
You forgot dots:
$sql="INSERT INTO review (username, movie_name, ratings)
VALUES (".$_POST['username'].",".$_POST['moviename'].",".$_POST['ratings'].")";
and fot the future for now your variables are not escaped so code is not secure
String in a SQL-Statment need ', only integer or float don't need this.
$sql="INSERT INTO review (username, movie_name, ratings) VALUES ('".$_POST['username']."','".$_POST['moviename']."','".$_POST['ratings']."')";