I am well-versed in the old php mysql extension.
I am working on my first script that uses the mysqli extension.
I am going to be inserting a large number of rows into a table that are being generated dynamically.
Is it possible to use a prepared statement to insert multiple rows into a table without previously knowing the number of new rows that will be inserted each time?
$stmt = $mysqli->prepare("INSERT INTO `activity` (`id`, `name`, `type`) VALUES ?, ?, ?;");
If that isn't possible, which would be more efficient:
prepared statement, one row at a time
non-prepared statement, ~50 rows at a time
// prepared statement
$stmt = $mysqli->prepare("INSERT INTO `activity` (`id`, `name`, `type`) VALUES (?, ?, ?)");
for($i=0;$i<$limit;$i++)
{
$stmt->bind_param('iss', $id[$i], $name[$i], $type[$i]);
$stmt->execute();
}
// non-prepared statement
$query = "INSERT INTO `activity` (`id`, `name`, `type`) VALUES ";
for($i=0;$i<$limit;$i++)
{
$query .= "\n(".$mysqli->real_escape_string($id[$i]), $mysqli->real_escape_string($name[$i]), $mysqli->real_escape_string($type[$i])."),";
}
$query = substr($query, 0, -1).';';
PHP v.5.3.8
MySQL v. 5.1.60
$stmt = $mysqli->stmt_init();
if($stmt->prepare("INSERT INTO `activity` (`id`, `name`, `type`) VALUES (?, ?, ?)"))
{
$stmt->bind_param('iss', $_id, $_name, $_type);
for($i=0;$i<$limit;$i++)
{
$_id = $id[$i];
$_name = $name[$i];
$_type = $type[$i];
$stmt->execute();
}
}
should do it for you!
Related
I am trying to protect my queries from SQL injections, recently. I have started turning the strings I used to make the queries into statements, however, some of the strings I made need to make multiple queries simultaneously, because one insert's id will be added to the next one as a foreign key, which I'll get by using the LAST_INSERT_ID(), and I need them to be executed one after another because of it.
Can a statement hold multiple queries simultaneously and be executed at once?
Here's what the code was before, by the by.
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES ('{$firstName}', '{$lastName}', '{$phone}', '{$cpf}');";
$sql .= "SELECT LAST_INSERT_ID() INTO #mysql_variable_here;";
$sql .= "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES ('{$email}','{$password}', 1, #mysql_variable_here, '{$created}', {$role}" . $restaurantValue . " );";
$sql .= "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES ('{$number}', '{$street}', '{$city}', '{$stateCode}', '{$zip}', '{$district}', 'BR', '{$created}', #mysql_variable_here);";
$result = $conn->multi_query($sql);```
You can't execute multiple statements in a prepared query:
SQL syntax for prepared statements does not support multi-statements
(that is, multiple statements within a single string separated by ;
characters)
so you will need to prepare and execute each of the queries separately, using mysqli_stmt::insert_id to get the appropriate id value for the second and third queries:
$sql = "INSERT INTO `user_info`(`first_name`, `last_name`, `phone`, `cpf`)
VALUES (?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssss', $firstName, $lastName, $phone, $cpf);
$stmt->execute();
$insert_id = $stmt->insert_id;
$stmt->close();
$sql = "INSERT INTO `{$table}`(`email`, `password`, `active`,`user_info_id`, `created`, `role_id`" . $restaurantInsert . ")
VALUES (?, ?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
$stmt->bind_param('ssiisss', $email, $password, 1, $insert_id, $created, $role, $restaurantValue);
$stmt->execute();
$stmt->close();
$sql = "INSERT INTO `address`(number, street, city, state, zip, district, country, created, user_info_id)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?);";
$stmt = $conn->prepare($sql);
$country = 'BR';
$stmt->bind_param('sssssssi', $number, $street, $city, $stateCode, $zip, $district, $country, $created, $insert_id);
$stmt->execute();
$stmt->close();
Note I'm not 100% certain what you're trying to achieve with role_id" . $restaurantInsert . ", you might need to edit the second query appropriately to use that.
I'm working into a Php Script to create fields in an online database, and the prepare() statement isn't working so I think I might fail in the query as I'm not good using SQL, here is the function;
function createQuestion($CAT, $PREG, $RESP1, $RESP2, $RESP3, $RESPC) {
$sql = "INSERT INTO `table1` (`ID`, `CAT`, `PREG`, `RESP1`, `RESP2`, `RESP3`, `RESPC`) VALUES (NULL, ?, ? , ?, ?, '?, ?)";
if ($stmt = $this->con->prepare($sql)) {
echo "prepare works okay!";
$stmt->bind_param("isssss", $CAT, $PREG, $RESP1, $RESP2, $RESP3, $RESPC);
if ($stmt->execute()) {
return true;
} else{
return false;
}
} else {
echo "prepare isn't working."
}
}
Apart from others errors specified in other classes, I'm getting the "prepare isn't working."
Your statement has a typo in it:
INSERT INTO `table1` (`ID`, `CAT`, `PREG`, `RESP1`, `RESP2`, `RESP3`, `RESPC`) VALUES (NULL, ?, ? , ?, ?, '?, ?);
Note the single ' mark in the VALUES(...) section? Try this instead:
INSERT INTO `table1` (`ID`, `CAT`, `PREG`, `RESP1`, `RESP2`, `RESP3`, `RESPC`) VALUES (NULL, ?, ?, ?, ?, ?, ?);
I've created this to insert to multiple tables, and I want to insert the same ID to both table. ID is auto-incremented in test table and I want test_category table to take the same ID.
I tried it but don't know where I am doing it wrong and getting an error
Fatal error: Call to undefined method mysqli_stmt::insert_id() in C:\wamp64\www\Android\include\DbOperations.php on line 27"
Check this pic for detailed error report
[https://www.dropbox.com/s/nuij2o2ac3xp8mz/Untitled4.png?dl=0]
My php
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?)");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$stmt->insert_id(),$name,$a,$b,$ho,$ll,$c,$d);
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
The "mysqli::$insert_id" is an attribute of mysqli object and your trying on $stmt
Try Following code will resolve your issue.
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?);");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$this->con->insert_id(),$name,$a,$b,$ho,$ll,$c,$d);
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
As of Documents
mysqli::$insert_id -- mysqli_insert_id — Returns the auto generated id used in the latest query
So instead of using $this->con->insert_id() you can use
$var = $this->con;
mysqli_insert_id($var);
Try putting your last inserted id in a variable and then pass it to your 2nd query.
public function testReg($name, $pin, $a, $b, $ho, $ll, $c, $d){
$stmt = $this->con->prepare("INSERT INTO `test` (`name`, `pin`) VALUES (?, ?);");
$stmt->bind_Param("ss",$name,$pin);
if(!$stmt->execute()){
return 2;
}else{
//ADDED ESLE AND STORE ID IN VAR
$lastid=$stmt->insert_id();
}
$stmttst = $this->con->prepare("INSERT INTO `test_category` (`pid`, `name`, `a`, `b`, `ho`, `ll`, `c`, `d`) VALUES (?, ?, ?, ?, ?, ?, ?, ?);");
$stmttst->bind_Param("isssssss",$lastid,$name,$a,$b,$ho,$ll,$c,$d);
// CHANGED BIND PARAM for last id
if ($stmttst->execute()){
return 1;
}else{
return 2;
}
}
Also, you shold specify if you are using mysqli or PDO as most people assume you are using PDO as it is most commonly used.
http://php.net/mysqli_multi_query might also help you in this case. Or try creating a second connectionto the BD, not just a 2nd statement.
You are probably looking for PDO::lastInsertId. It returns the ID of the last inserted row. Therefore you can use this in your second query as it will hold the ID of the first. More info here: http://php.net/manual/en/pdo.lastinsertid.php
Hi How can i incorporate On Duplicate Key with mysqli_stmt_bind_param
$stmt = mysqli_prepare($con, "INSERT INTO assy (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE partid=$bom");
mysqli_stmt_bind_param($stmt, "ssii", $itemid, $bom, $qty, $bomEntry) or die(mysqli_error($con));
$recordd = $tv->search(454545400000, 's=2');
//print_r($recordd);echo"1<br/>";
foreach($recordd as $data2) {
$itemid = $data2['fields']['CALC STOCK NO'];
$bomEntry = 1;
if ($data2['fields']['BOM WHEEL PN']) {
$bom = $data2['fields']['BOM WHEEL PN'];
$qty=1;
mysqli_stmt_execute($stmt) or die(mysqli_stmt_error($stmt));
$bomEntry++;
}
}
I tried something like
$stmt = mysqli_prepare($con, "INSERT INTO table_name (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE patid=$bom;");
.
.
.
but it set to blank
Your $bom is a string so it need to be quoted, or preferably swapped out of the query and bound via a placeholder. Here is the placeholder and binding approach:
$stmt = mysqli_prepare($con, "INSERT INTO assy (ItemID,partid,qty,rev,bomEntry) VALUES (?, ?, ?, 'A',?) ON DUPLICATE KEY UPDATE partid=?");
mysqli_stmt_bind_param($stmt, "ssiis", $itemid, $bom, $qty, $bomEntry, $bom);
With prepared statements you rarely will want variables in your query.
I need to execute 2 or more not identical queries (INSERT's in this example.) using PHP's prepared statements and MySQL's transactions. So if I have a 2 INSERT statements, I want both of them executed, or none of them.
I want to traslate this example MySQL transaction to a PHP code:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
PHP code I'm working on:
mysqli_autocommit($connection, FALSE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
PHP code above works but what if I have more critical statements to execute? Is there are good way to execute statements with PHP's prepared statemens and transactions at the same time?
Please note that for $stmtComplementaryFile I must have a mysqli_insert_id() value. Also please note that I am not using PDO with this code — I appreciate if suggestions will be MySQLi. Thanks.
The following SQL:
START TRANSACTION;
INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES ('file.png', 'image/png', '1024', 'My comment');
INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (LAST_INSERT_ID(), '1');
COMMIT;
Can be converted to PHP (with prepared statements) as follows:
mysqli_begin_transaction($connection, MYSQLI_TRANS_START_READ_WRITE);
if ($stmtFile = mysqli_prepare($connection, "INSERT INTO `file` (`name`, `mime_type`, `size`, `comment`) VALUES (?, ?, ?, ?)")) {
mysqli_stmt_bind_param($stmtFile, 'ssis', $name, $mime_type, $size, $comment);
if (mysqli_stmt_execute($stmtFile)) {
if ($stmtComplementaryFile = mysqli_prepare($connection, "INSERT INTO `complementary_file` (`file_id`, `user_id`) VALUES (?, ?)")) {
mysqli_stmt_bind_param($stmtComplementaryFile, 'ii', mysqli_insert_id($connection), $user_id);
mysqli_stmt_execute($stmtComplementaryFile);
}
} else {
mysqli_rollback($connection);
}
}
mysqli_commit($connection);
In general these two statements are equivalent, however it's a good idea to know what transactions are and what transactions are not.
Transactions are a mechanism to ensure that bulk operations are executed atomically and their results are reflected in the database only if ALL of them succeed. It ensures atomicity of operations.
Transactions are not a mechanism to implement a mutual exclusion lock on the tables. If a table needs to be locked then the LOCK TABLES [READ|WRITE] needs to be used. Equivalently in PHP this is achieved by doing a:
mysqli_query($connection, "LOCK TABLES tableName as TableAlias [read|write]");
followed by
mysqli_query($connection, "UNLOCK TABLES");