RollBack () and beginTransaction() not work in my PHP PDO and my table type is innoDB. In the following code my $sql1 is correct and my $sql2 is wrong (I added d to $last_id to just make it wrong). But it still executes sql1 meaning roll back no effect. Thank you for your advice.
<?php
include 'connect.php';
// Get multiple input field's value
try {
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// Starts our transaction
$conn->beginTransaction();
foreach ($_POST['phone'] as $value) {
$sql1 = "INSERT INTO tbl_contact_info (type)
VALUES ('$value')";
// use exec() because no results are returned
$conn->exec($sql1);
$last_id = $conn->lastInsertId();
$sql2="INSERT INTO tbl_img (img_type)
VALUES ('$dlast_id')";
$conn->exec($sql2);
}
// Commits out queries
$conn->commit();
echo "New record created successfully";
}
catch(PDOException $e)
{
// Something borked, undo the queries!!
$conn->rollBack();
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
?>
First of all (and sorry it it's obvious but I realised it's not always clear to everyone) SQL and PHP are different languages. MySQL Server will not react to Undefined variable notices triggered in PHP code.
Secondly, notices are not exceptions so they cannot be caught with try/catch statements. (You can certainly write a custom error handler that will throw exceptions on errors but it doesn't seem to be the case here.)
I'm learning to connect to my database and create/read/update/delete information from different tables. Currently I'm using PDO instead of mysqli because I'm having an easier time with prepared statements. What I'm trying to do right now doesn't actually have any value, I just want to know WHY this is happening. Here's my code:
//pdo connection
try {
$conn = new PDO("mysql:host={$db_host};dbname={$db_name}", $db_user, $db_pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//READ FROM DB
$stmt = $conn->prepare('SELECT * FROM objects where ID = :id');
$stmt->execute(array(':id'=>8));
print_r($stmt->fetch(PDO::FETCH_OBJ));
while($row = $stmt->fetch(PDO::FETCH_OBJ)) {
$results[] = $row;
}
print_r($results);
} catch(PDOException $e) {
echo 'ERROR: ' . $e->getMessage();
}
Now, what's happening is that if I print_r in this order then only the first print_r works and vice versa (assuming I also move the while loop with the print_r($results) statement. Why is it that I am only allowed to do this once and whichever is first negates the second?
EDIT: Clarification.
Ok, so I've been trying to do this for days, and I've been reading all sorts of tutorials, but I seem to be missing something, because I still can't get it. I'm working on learning about web forms and inserting the form input into the respective database. I'm able to take the info from the form and echo it on the result page, so I know that all works. but I can't seem to get the form input to go into my database. I know the connection works, so there must be something wrong with my syntax.
PHP
//DB Configs
$username = null;
$password = null;
try {
$db = new PDO("mysql:host=localhost;dbname=Testing3", $username, $password);
//Set the PDO error mode to exception (what does this mean?)
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Prepare SQL and bind parameters
$sql = $db->prepare("INSERT INTO `NFK_SPECIES` (`Name`)
VALUES (:name)");
//Insert a Row
$species = $_POST['Species'];
$sql->execute(array(':name'=>$species));
}
catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
$result = $db->query('SELECT * from `NFK_Species` ORDER BY `Id` DESC');
//Query
/*
$input = $db->query("INSERT INTO `NFK_Species` (`Id`, `Name`) VALUES (Null, `$species`)");
$result = $db->query('SELECT * from `NFK_Species` ORDER BY `Id` DESC');*/
//Kill Connection
$db = Null;
}
HTML/PHP (web page)
<h1>Inserting a New Species into Database:</h1>
<h3>Results</h3>
<?php
if ($sql->execute()){
echo "Data input was successful";
while ($rows = $result->fetch()){
echo $rows['Name']; echo ", ";
}
} else {
echo "Data input failed."; echo mysql_error();
}
?>
This is only my current attempt at doing this. I prefer the attempt I had before, with the bindParam and simple execute(), so if I could get that to work instead, I'd appreciate it. The following example also has the Id column for this table. This is an auto-increment column, which I read doesn't need to be included, so I excluded it from my recent attempt. Is that correct?
Past PHP
//Prepare SQL and bind parameters
$sql = $db->prepare("INSERT INTO `NFK_SPECIES` (`Id`, `Name`)
VALUES (Null, :name)");
$sql->bindParam(':name', $species);
//Insert a Row
$species = $_POST['Species'];
$sql->execute();
I've been reading a bunch of tutorials (or trying to), including attempting to decipher the php.net tutorials, but they all seem to be written for people who already have a good handle on this and experience with what's going on, and I'm very new to all of this.
Alright, I was able to figure out my problem, and then successfully insert a row using my code.
Debugging:
So the code posted above was breaking my code, meaning my page wouldn't load. I figured that meant that there was a syntax error somewhere, but I couldn't find it, and no one else had located it yet. Also, that meant that my Error Alerts weren't working to let me know what the problem was. If you look at my original PHP sample, you'll see down at the very bottom there is a single "}" just hanging out and serving no purpose, but more importantly, it's breaking the code (stupid, hyper-sensitive php code). So I got rid of that, and then my Error messages started working. It said I couldn't connect to my database. So I look over my database login syntax, which looked fine, and then you'll notice in my 1st php sample that somehow I'd managed to set my $username and $password to NULL. Clearly that isn't correct. So I fixed that, and next time I refreshed my page, I'd successfully entered a row in my database! (yay)
Note:
In my original php sample, I'd included the Id Column, which is auto-incremented, for the row insertion, with a value of NULL. This worked, and it inserted the row. Then I experimented with leaving it out altogether, and it still worked. So the updated working code below doesn't include the Species Id.
Working code:
<body>
<h1>Inserting a New Species into Database:</h1>
<h3>Results</h3>
<?php
//DB Configs
$username = root;
$password = root;
try {
//Connect to Database
$db = new PDO("mysql:host=localhost;dbname=Testing3", $username, $password);
//Enable PDO Error Alerts
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Prepare SQL statement and bind parameters
$sql = $db->prepare("INSERT INTO `NFK_SPECIES` (`Name`) VALUES (:name)");
$sql->bindParam(':name', $species);
//Insert a Row
$species = $_POST['Species'];
$sql->execute();
// Echo Successful attempt
echo "<p class='works'><b>" . $species . "</b> successfully added to database.</p></br></br>";
}
catch (PDOException $e) {
echo "Error: " . $e->getMessage();
}
// Gather updated table data
$result = $db->query('SELECT * from `NFK_Species` ORDER BY `Id` DESC');
//Kill Connection
$db = Null;
while ($rows=$result->fetch()){
echo $rows['Id']; echo " - "; echo $rows['Name']; echo "</br>";
}
?>
<body>
I have a transaction that does an insert into several tables. I want to catch any errors so that if any of the inserts fail they will all be rolled back. Here is a short version of what I am trying to do:
try {
$this->conn->beginTransaction();
//build an sql insert...
$sql = "INSERT INTO...
$stmt = $this->conn->prepare($sql);
$stmt->execute();
//do more inserts...
//commit the transaction
$this->conn->commit();
$this->message = 'The Program has been added.';
//catch errors and rollback
} catch (PDOException $e) {
$this->message = $e->getMessage();
$this->conn->rollBack();
}
All of the inserts work properly but if there is a problem, I don't seem to be catching the error and the rollback does not happen. For instance, if I write bad sql or don't pass values for parameters, I just get php errors but the inserts proceed anyway. I can post the full code if it helps but maybe it is something obvious?
Using SQLite in PHP (thus using PDO), I have this code:
try {
$db = new PDO("sqlite:C:\Program Files\Spiceworks\db\spiceworks_prod.db");
echo "Done.<br /><b>";
$query = "SELECT id FROM Devices LIMIT 5";
echo "Results: ";
$result = $db->query($query);
while ($row = $result->fetchArray()) {
print_r($row)."|";
}
}
catch(PDOException $e) {
echo $e->getMessage();
}
But that does not print out any data from the SQL. I know the database has data in it and the connection is valid. If I change the query to say:
$query = "SELECT BLAHid FROM FakeDevices LIMIT 5";
Nothing changes. Nothing from SQL gets printed out again, and I see no errors even though this is clearly an invalid SQL query.
In both situations, the "Done" and "Results" gets printed out okay. How can I print out SQL errors, like if the query is invalid?
You need to tell PDO to throw exceptions. You can do that by adding the following line after you connect to the database:
$db = new PDO("sqlite:C:\Program Files\Spiceworks\db\spiceworks_prod.db");
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
That way you can catch all exceptions except for a possible problem with the first line, the database connection itself.