Executing Multiple Queries Using PDO - php

I am trying to execute the following query using a PDO Prepared Statement, but when I call $query->fetch(); it throws an exception SQLSTATE[HY000]: General Error.
This is the PHP code (note that class Database - or the variable $db in code - is just a simple wrapper for the class PDO thus all PDO calls have to be done using $db->pdo->{some PDO function}();):
$db = new Database(); //Create a new object of type Database establishing a connection to the MySQL database
$query = $db->pdo->prepare("INSERT INTO `orders` (`order_type`, `item`, `amount`, `price`, `price_btc`, `status`, `timestamp`, `placed_by`, `secret`, `first_name`, `last_name`, `address_1`, `address_2`, `city`, `zip_code`, `country`, `state`, `phone_number`)
VALUES(:order_type, :item, :amount, :price, :price_btc, :status, :timestamp, :placed_by, :secret, :first_name, :last_name, :address_1, :address_2, :city, :zip_code, :country, :state, :phone_number);
SELECT * FROM `orders` WHERE `ID`=LAST_INSERT_ID();"); //Prepare the two queries to be executed
/*HERE IS SOME CODE TO BIND PLACEHOLDERS TO SOME VALUES*/
if(!$query->execute()){
error(); //Handle the error and terminate execution
}
if($query->rowCount() != 1){
error(); //Handle the error and terminate execution
}
$query->setFetchMode(PDO::FETCH_ASSOC);
$order = $query->fetch(); //THIS IS WHERE THE EXCEPTION IS THROWN!
I have tried executing the query manually through PHPMyAdmin and it worked fine. I've also read that PDO doesn't support multiple queries in the same statement, but shouldn't it then throw and exception when running $query->execute();?
Also, $query->rowCount(); DOES return 1, but when I try to fetch the result it throws a general error exception.
I have tried a lot of other things like replacing the SELECT statement with a SELECT LAST_INSERT_ID();, but nothing seems to work.
I would appreciate your help!

Run your first query which is the insert then after success on that one get the last insertid then use the id on your next query.. Eg.
<?php
try {
$db = new Database(); //Create a new object of type Database establishing a connection to the MySQL database
$query = $db->prepare("INSERT INTO orders (order_type`, `item`, `amount`, `price`, `price_btc`, `status`, `timestamp`, `placed_by`, `secret`, `first_name`, `last_name`, `address_1`, `address_2`, `city`, `zip_code`, `country`, `state`, `phone_number`) VALUES(:order_type, :item, :amount, :price, :price_btc, :status, :timestamp, :placed_by, :secret, :first_name, :last_name, :address_1, :address_2, :city, :zip_code, :country, :state, :phone_number)");
$query->execute(array( /* your values*/ ));
$lastId = $db->lastInsertId(); // fetch last insert id, after success.
$order = $db->prepare("SELECT * FROM `orders` WHERE `ID`=?");
$order->bindValue(1, $lastId);
$order->execute();
//Fetch your records and display.
}
catch (PDOException $e) {
echo "Error : " . $e->getMessage();
}
?>
I left some part of the codes like you did, but the important thing is to run the insert first then collect the last

You don't need a multiple statement.
So just run your queries one by one
$db = new Database(); //Create a new object of type Database establishing a connection to the MySQL database
$query = $db->pdo->prepare("INSERT INTO `orders` (`order_type`, `item`, `amount`, `price`, `price_btc`, `status`, `timestamp`, `placed_by`, `secret`, `first_name`, `last_name`, `address_1`, `address_2`, `city`, `zip_code`, `country`, `state`, `phone_number`)
VALUES(:order_type, :item, :amount, :price, :price_btc, :status, :timestamp, :placed_by, :secret, :first_name, :last_name, :address_1, :address_2, :city, :zip_code, :country, :state, :phone_number)"
); //Prepare the first query
/*HERE IS SOME CODE TO BIND PLACEHOLDERS TO SOME VALUES*/
$query->execute();
$order = $db->pdo->query("SELECT * FROM `orders` WHERE `ID`=LAST_INSERT_ID()")->fetch(PDO::FETCH_ASSOC);

You would be correct in that PDO (and I believe any PHP method?) does not allow for multiple queries in a single by default. There are some workarounds which you can read about more, such as:
PDO support for multiple queries (PDO_MYSQL, PDO_MYSQLND)
but they do increase the risk of SQL injection so it is ill-advised.

Related

INSERT into mysql DATABASE Prepared Statments

Can anybody see why this is not inputting into my database..
I did have it working, but now i got the error on mysql A form on this field has more than 1000 fields, but none of them do....
here is the prep statment
$db = new PDO("mysql:host=localhost;dbname=class2", 'root', '');
$query="INSERT INTO `testdata` (`1st name`, `2nd name`, `title`, `info`, `location`, `phone`, `postcode`, `image`, `image2`, `image3`, `image4`, `image5`, `price`, `catagory`, `cond`, `delivery`, `email`, `username`, `youtubevideo`, `paypal`, `facebook`, `twitter`, `feedbackscore`)
VALUES (?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
$stat=$db->prepare($query);
$stat->execute(array("$firstname","$lastname","$sellingtitle","$sellinginfo","$town","$phone1","$postcode","$i0url","$i1url","$i2url","$i3url","$i4url","$price","$catagory","$cond","$delivery","","$sellername","$youtubeurl","$paypal","$facebook","$twitter","feedbackscore"));
Your PDO is not prepared correctly.
$database = new PDO("mysql:host=localhost;dbname=class2", 'root', '');
$query = "UPDATE users SET first_name = :first_name, last_name = :last_name
WHERE user_id = :user_id";
$update = $database->prepare($query);
$update->execute([
':first_name' => $_POST['firstname'],
':last_name' => $_POST['lastname'],
':user_id' => $_SESSION['user_id']
]);
$update->fetch();
With PDO you define the keys of the values in the prepare string like :first_name.
So then in the execute function's array, you define the values of these keys.
Hope it helps.

insert data by GET

I want insert data by GET in my sql but I can not insert data
<?php
include("config.php");
$f=$_GET["first_name"];
$l=$_GET["last_name"];
$e=$_GET["email"];
$m=$_GET["mobile"];
$b=$_GET["birthday"];
$g=$_GET["gender"];
$insert="INSERT INTO user ( `first_name`, `last_name`, `email`, `mobile`, `birthday`, `gender`)
VALUES ('$f', '$l', '$e', '$m', '$b', '$g')";
mysqli_query($insert);
?>
I try insert data by this link :
http://localhost:8888/restfull/insert.php?f=hayoo
It's been a long time since I have used mysqli the code below should most likely run though. As others have mentioned never bind unsanitized data (Even if you think you trust the data it's safe to use prepared statements still).
<?php
//Create you db connection
$conn = new mysqli('server', 'user', 'password', 'databasename');
//Create insert statement. Never concat un-sanitized data in statements
$insert="INSERT INTO user ( `first_name`, `last_name`, `email`, `mobile`, `birthday`, `gender`)
VALUES (?, ?, ?, ?, ?, ?)";
$stmt = $conn->prepare($sql);
//Values corespond to ? except the first param which represents format of expected data. "s" stands for string
$stmt->bind_param(
'ssssss',
$_GET["first_name"],
$_GET["last_name"],
$_GET["email"],
$_GET["mobile"],
$_GET["birthday"],
$_GET["gender"]
);
$stmt->execute();
Your url would look like this:
http://localhost:8888/restfull/insert.php?first_name=john&last_name=Doe&email=test#test.com&mobile=0&birthday=May&gender=male
Make sure if you are putting the url above in some type of form you correctly url encode values (I notice many of the values you are collecting will like require it slashes etc).

How to execute multiply queries using PHP's prepared statemens with MySQL's transaction?

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");

Is it possible to combine mysqli prepared statement with multiple inserts?

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!

php prepared statement fails.

I'm guessing I'm missing something, but I can't seem to get this statement to work. When I load it into the page I get the white screen of death.
Here is what I'm trying to get to run
$statement = $db-> prepare("INSERT INTO `simplyaccomplished`.`blog_comment` (`ID`, `comment`, `date`, `ip_address`, `valid`, `name`, `blogcomment_ID`) VALUES (NULL, ?, NOW(), ?, 0, ?, ? );");
$statement -> bind_param("sssi",$comment, $ipaddress, $name , $comment_id);
$statement -> execute($statement);
$statement -> close();
The weird thing is this runs perfectly
$query = ("INSERT INTO `simplyaccomplished`.`blog_comment` (`ID`, `comment`, `date`, `ip_address`, `valid`, `name`, `blogcomment_ID`) VALUES (NULL,'$comment' , NOW(), '$ipaddress', '0', '$name', '$comment_id');");
$result =$db->query($query);
If someone could tell me where I'm going wrong I would greatly appreciate it!
The PDO method you're looking for is named bindParam, not bind_param :)
Try mysqli method,
$statement = $db-> prepare("INSERT INTO `simplyaccomplished`.`blog_comment` (`ID`,
`comment`, `date`, `ip_address`, `valid`, `name`, `blogcomment_ID`)
VALUES (?, ?, ?, ?,?, ?, ?)");
$statement -> bind_param("ssssisi",
null,$comment,NOW(),$ipaddress, 0,$name , $comment_id);
Take a look at PDO and MySqlI.

Categories