New to mySQL PDO. I have read other answers here and read tutorials and am finally taking the plunge. Problem is I cannot seem to output data. Hence, can someone assess my code to ensure it is correct? Also, is the system I am using to query the db efficient and clean and secure? thanks
$pdo --- the correct connection information is in this line but has been removed ---
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// SELECT sql query
try {
$thedate='2013-06-03';
$rotation=1;
$stmt = $pdo->prepare("SELECT * FROM sched_main_2013 WHERE thedate=:thedate AND rotation=:rotation");
$stmt->bindValue(':thedate', $thedate, PDO::PARAM_STR);
$stmt->bindValue(':rotation', $rotation, PDO::PARAM_INT);
$stmt->execute();
$stmt->setFetchMode(PDO::FETCH_ASSOC);
}
catch(PDOException $ex) {
echo $ex->getMessage();
}
while($rows = $stmt->fetch()) {
echo $rows['thedate'] . "\n";
echo $rows[assignedRad] . "\n";
echo $rows[rotation] . "\n";
}
// close the connection
$pdo = null;
This code outputs nothing. No errors. Nothing at all.
By the way, the table exists and the SELECT * FROM works fine when I manually run the mySQL statement, so data does exist with this query.
Try
while($rows = $stmt->fetch()) {
echo $rows['thedate'] . "\n";
echo $rows[assignedRad] . "\n";
echo $rows[rotation] . "\n";
}
To
while($rows = $stmt->fetch()) {
echo $rows['thedate'] . "\n";
echo $rows['assignedRad'] . "\n";
echo $rows['rotation'] . "\n";
}
Debug 01
Maybe you can try this to test whether you truly receive any data from database
print_r($stmt->fetchAll());
Instead of your while-loop
Debug 02
Try the simple query that you strongly believe there will be no SQL error for example:
SELECT * FROM sched_main_2013
Without any value binding.
Debug 03
Try another query with WHERE condition, but no binding
SELECT * FROM sched_main_2013 WHERE thedate='2013-06-03' AND rotation=1
You told that var_dump($row) gives you FALSE. The documentation says:
The return value of this function on success depends on the fetch type. In all cases, >FALSE is returned on failure.
Add the following line:
while($row = $stmt->fetch()) {
echo $row['thedate'] . "\n";
echo $row['assignedRad'] . "\n";
echo $row['rotation'] . "\n";
}
if($row === FALSE) {
var_dump($stmt->errorInfo());
die();
}
Further note: You originally named the return value of $stmt->fetch() $rows (plural) instead of $row. I'm not sure whether you know that the method will return a single row each time it is called.
What it have to be
$sql = "SELECT * FROM sched_main_2013 WHERE thedate=? AND rotation=?";
$data = array('2013-06-03', 1);
$stmt = $pdo->prepare($sql);
$stmt->execute($data);
$rows = $stmt->fetchAll();
var_dump($rows);
$sql = "SELECT * FROM sched_main_2013";
$data = array();
$stmt = $pdo->prepare($sql);
$stmt->execute(array());
$rows = $stmt->fetchAll();
var_dump($rows);
If second query returns the rows while first doesn't - there is no data found.
If both returns no rows - then it is caused by bad database design which is clearly seen from the table name, which should never have a postfix like this
Related
I'm trying to loop through a stored procedure, called via prepared statement, in PHP. Hopefully it's not impossible. Here's my PHP code:
$database = new mysqli($server, $user, $pass, $db);
$stmt = $database->prepare("CALL thisShouldReturnEightResultSets (?)");
$stmt->bind_param("i", $id);
$stmt->execute();
do {
if ($res = $stmt->bind_result($myvar)) {
$stmt->fetch();
echo "*" . $myvar . "<br/>";
} else {
if ($stmt->errno) {
echo "Store failed: (" . $stmt->errno . ") " . $stmt->error;
}
}
} while ($stmt->next_result());
That should print like so:
* 4
* 16
* 7
etc...
... and then exit once it runs of out result sets. Instead I get:
* 4
Fatal error: Call to undefined method mysqli_stmt::next_result()
At first I tried get_result instead of bind_result, but that errored. Based on this I found that I don't have the mysqlnd driver installed. Iworked around that with bind_result. Now I need a work around for next_result which I'm guessing is part of the mysqlnd driver as well. What are my options here? Tech notes:
PHP Version 5.3.2-1ubuntu4.11
Thanks.
I don't think you can do this with a prepared statement, since you don't have the MYSQLND driver. You'll have to do it the old fashioned way, with escaping.
$id = $database->real_escape_string($id);
if ($database->multi_query("CALL thisShouldReturnEightResultSets ('$id')")) {
do {
if ($result = $database->store_result()) {
while ($row = $result->fetch_row()) {
echo "*" . $row[0] . "<br/>";
}
}
} while ($database->next_result());
}
bindResult does not like multiple results.
Use get_result() then fetch_assoc and store in an array,
Then use a foreach loop to output your results.
$res = $stmt->get_result();
$array[];
while($x = $res->fetch_assoc()){
$array[]=$x;
}
I am trying to execute a SQL query and it does not work.
$sql = "SELECT top 5 AccountDocument from web.Preoffers_new where AccountDocument = 'xxxxxxxx'";
$stmt = $db->prepare($sql);
$stmt->execute();
if ($data = $stmt->fetch()) {
do {
echo $data['AccountDocument'] . '<br>';
} while ($data = $stmt->fetch());
} else {
echo 'Empty Query';
}
This works perfectly and shows me the results.
But this:
$sql = "SELECT top 5 Document from Companies where Document = 'xxxxxxxx'";
$stmt = $db->prepare($sql);
$stmt->execute();
if ($data = $stmt->fetch()) {
do {
echo $data['Document'] . '<br>';
} while ($data = $stmt->fetch());
} else {
echo 'Empty Query';
}
Go directly to Empty Query. But is not true because if I execute that query in SQL it works perfectly.
The only diferent i see is the first one query go to a table in the DB and the second one go to a one view...
Some clues could be this?
SET
ANSI_NULLS,
QUOTED_IDENTIFIER,
CONCAT_NULL_YIELDS_NULL,
ANSI_WARNINGS,
ANSI_PADDING
ON;
UPDATE ---->
i set the attribute PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION for see if the server show me something and I received this:
Error conectando con la base de datos: SQLSTATE[HY000]: General error: 1934 General SQL Server error: Check messages from the SQL Server [1934] (severity 16) [SELECT top 5 Document from Companies where Document = 'xxxxxxxx']
I checked the error in SQL and I get this:
%ls failed because the following SET options have incorrect settings: '%.*ls'. Verify that SET options are correct for use with %S_MSG..
Anyone have any idea why I can not make queries in views?
Thanks for reading me :)
As i see in code you use "Document" instead of "AccountDocument" So replace AccountDocument with Document.
$sql = "SELECT top 5 Document from Companies where Document = 'xxxxxxxx'";
$stmt = $db->prepare($sql);
$stmt->execute();
if ($data = $stmt->fetch()) {
do {
echo $data['Document'] . '<br>';
} while ($data = $stmt->fetch());
} else {
echo 'Empty Query';
}
I am trying to get both the results of my query and the row count wihtout having to make two trips the the DB if possible. I am using prepared statements in a procedural way. My code is as follows:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
So the above code works just fine and returns my results. What I want to do now is get the row count using this same statement but i don't want to have to write a brand new prepared statement. If I writer a separate prepared statement and use store_results and num_rows I get the row count but that would force me to have to write an entire new block of code and trip to db. I am trying to do something as follows but It throws and error:
$dbd = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($dbd, "SELECT * FROM Contacts WHERE First_Name = ?" )) {
mysqli_stmt_bind_param($dbd, "s", $val1);
if (!mysqli_stmt_execute($dbd)) {
echo "Execute Error: " . mysqli_error($dbconnection);
} else {
//do nothing
}
} else {
echo "Prep Error: " . mysqli_error($dbconnection);
}
$result = mysqli_stmt_get_result($dbd);
mysqli_stmt_store_result($dbd);
$rows = mysqli_stmt_num_rows($dbd);
The throws and error as if i can't run both get results and store results using the same prepared statement. Im simply trying to keep my code compact and reuse as much as possible. If i break the above out into two separat prepared statements it works fine, Im just wondering there is a way to just add a line or two to my existing statement and get the row count. Or do i have to write an entire new block of code with new stmt_init, stmt_prepare, bind_param, execute, etc...
I tried your code (and reformatted it a bit), but I can't get it to work when I use both store_result() and get_result(). I can only use store_result then bind_result().
So the alternative is to fetch all the rows and then count them:
Example:
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = mysqli_stmt_init($dbconnection);
if (mysqli_stmt_prepare($stmt, $sql) === false) {
trigger_error("Prep Error: " . mysqli_error($dbconnection));
return 1;
}
if (mysqli_stmt_bind_param($stmt, "s", $val1) === false) {
trigger_error("Bind Error: " . mysqli_stmt_error($stmt));
return 1;
}
if (mysqli_stmt_execute($stmt) === false) {
trigger_error("Execute Error: " . mysqli_stmt_error($stmt));
return 1;
}
$result = mysqli_stmt_get_result($stmt);
$rows = mysqli_fetch_all($result, MYSQLI_ASSOC);
$num_rows = count($rows);
print "$num_rows rows\n";
foreach ($rows as $row) {
print_r($row);
}
In my opinion, PDO is much easier:
$pdo = new PDO("mysql:host=127.0.0.1;dbname=test", "xxxx", "xxxxxxxx");
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, true);
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
$sql = "SELECT * FROM Contacts WHERE First_Name = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$val1]);
$num_rows = $stmt->rowCount();
print "$num_rows rows\n";
while ($row = $stmt->fetch()) {
print_r($row);
}
I'm using PDO to grab records from a mysql table. The data will be encoded with json_encode() and printed through the Slim framework for the API:
$app->get('/get/profile/:id_user', function ($id_user) use ($app) {
$sql = 'SELECT * FROM user WHERE id_user = :id_user';
try {
$stmt = cnn()->prepare($sql);
$stmt->bindParam(':id_user', $id_user, PDO::PARAM_INT);
$stmt->execute();
$data = $stmt->fetch(PDO::FETCH_ASSOC); // THIS!!!
if($stmt->rowCount()) {
$app->etag(md5(serialize($data)));
echo json_encode($data,JSON_PRETTY_PRINT);
} else {
$app->notfound();
}
} catch(PDOException $e) {
echo $e->getMessage();
}
});
Should I use
$data = $stmt->fetch(PDO::FETCH_ASSOC);
or
$data = $stmt->fetchObject();
? Any direct benefits on fetching the data as an object? I've read some examples but they never explain why. The only usage for the resulting data will be to print it in JSON format. Thanks!
It doesn't matter. Though I'd cut an object out with Occam's razor.
Also your code is slightly wrong and redundant. Here is a proper version
$sql = 'SELECT * FROM user WHERE id_user = :id_user';
$stmt = cnn()->prepare($sql);
$stmt->bindParam(':id_user', $id_user, PDO::PARAM_INT);
$stmt->execute();
if ($data = $stmt->fetch()) {
$app->etag(md5(serialize($data)));
echo json_encode($data,JSON_PRETTY_PRINT);
} else {
$app->notfound();
}
there is no point in setting fetch mode for the every query when you can set it globally.
numrows() call is also useless.
and of course catching an exception is redundant, insecure and unreliable.
I have the following code:
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
$query = $link->prepare("SELECT * FROM index WHERE sbeid=:idvar");
for($j = 1; $j < count($array); $j++)
{
if($array[$j][16] == "TRUE" || $array[$j][16] == "FALSE")
{
$paramforquery = $array[$j][25];
$query->bindParam(":idvar",$paramforquery);
$query->execute();
$result = $query->fetchAll();
//do things with the $result
$query->closeCursor();
}
//else if, do stuff
}
$link = null;
$array is a large array composed of input from a CSV file that successfully loads via fopen().
My problem is this: the query just doesn't work. I know for a fact (ran the query directly on the server with some sample values from the file) that the data is in the database, but when i var_dump the $results each time the for loop runs, I just get an empty array.
What am I doing wrong?
TIA.
Increase the error reporting - the standard advice.
Set the error mode of the pdo object to ERRMODE_EXCEPTION - you hardly can miss an error that way.
Use a debugger or add some debug output to your script - a real debugger is way better.
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
$array = foo();
echo '<pre>Debug: |array|=', count($array), '</pre>';
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
$link->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$query = $link->prepare("SELECT * FROM index WHERE sbeid=:idvar");
$query->bindParam(":idvar", $paramforquery);
foreach($array as $row) {
echo '<pre>Debug: row[16]='; var_dump($row[16]); echo '</pre>';
if($row[16] == "TRUE" || $row[16] == "FALSE") {
$paramforquery = $row[25];
echo '<pre>Debug: paramforquery='; var_dump($paramforquery); echo '</pre>';
$query->execute();
echo '<pre>Debug: rowcount='; var_dump($query->rowCount()); echo '</pre>';
$result = $query->fetchAll();
//do things with the $result
$query->closeCursor();
}
//else if, do stuff
}
$link = null;
Are you sure you are getting a connection ?
try {
$link = new PDO("mysql:dbname=$databasename;host=127.0.0.1",$username,$password);
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
}
This will catch any exceptions from trying to connect. If this works ok, try putting the query under the $link line and see what's returned.
If your query runs manually, i'd say its something to do with your DB connection. Make sure you've got error reporting turned on.
Additional:
In your query you have this :idvar ? Shouldnt you be using a PHP variable like this $idvar.
so
$query = $link->prepare("SELECT * FROM index WHERE sbeid=" . $idvar);