PHP PDO Binding Time Variables for Postgresql Query - php

Folks, I'm having trouble debugging this. Please note that after testing the query in Elephant Postgresql, I can verify the query works when a string literal is handed over in the interval cast:
function get_most_popular_posts($dbh, $count = 10, $from = 0) {
try{
$option = strval($from);
$newfrom = $option.' seconds';
//var_dump($from);
$sql = 'WITH top_voted AS(
SELECT COUNT(post_id), post_id FROM VotedBy GROUP BY post_id
), res AS (SELECT id AS pid, author AS username, title,
body AS content, posted AS time,
coordX AS coorX, coordY AS coorY, COUNT FROM Posts, top_voted
WHERE Posts.id = top_voted.post_id AND posted >= (current_timestamp - interval :newfrom))
SELECT pid, username, title, content, time, coorx, coory FROM res ORDER BY COUNT DESC, time DESC LIMIT :count;';
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':count', $count);
$stmt->bindParam(':newfrom', $newfrom);
$stmt->execute();
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
//var_dump($stmt);
//var_dump($result);
//var_dump($newfrom);
Please help. Var_dumping the bound variable suggests that the concatenation works.

Related

PHP MySQL How to select 2 specific and 1 common value over 2 tables?

i have here two tables (only the important columns listed) :
table1: unique_code(INT), spediteur(VARCHAR also Names),
table2: unique_code(INT), versendet(timestamp)
I have here a SELECT but that don't work and if the value is true - that means: just let me into the IF WHEN: spediteur value is Name and versendet = 0000-00-00 00:00:00 and unique_code = $value (unique_code/$value must be equal in this two tables).
I have tried with this:
$pdo = new PDO('myconnectionworks')
$stmt = pdo->prepare("SELECT * FROM table1 WHERE spediteur = 'Name' AND unique_code = $value
UNION ALL
SELECT * FROM table2 WHERE versendet = '0000-00-00 00:00:00' AND unique_code = $value");
$stmt->execute([$value]);
$result = $stmt->fetch();
if ($result){ "the unique_number exists in both tables and matches the id with the value spediteur 'Dachser' in table1 AND the value versendet ='0000-00-00 00:00:00' in table2" } else { "anything doesn´t work" }
This does not work, as it don´t allow me to get into the if , just into the else section.
IF is a response for a successful action (save a other value) and else was an Error Response.
Did you have hints for me?
EDIT with Solution. i have used a programm that helps me to figure out, what for a statement i can use. (dbForge QUery Builder for MySQL)
Okay here ist the Statement:
$stmt = $pdo->prepare("SELECT
table1.spediteur,
table2.versendet,
table2.unique_code,
table1.unique_code
FROM table1
INNER JOIN table2
ON table1.unique_code = table2.unique_code
WHERE table1.unique_code = $scanned_number
AND table2.unique_code = $scanned_number
GROUP BY table1.spediteur,
table2.versendet,
table2.unique_code,
table1.unique_code
HAVING table1.spediteur = 'Dachser'
AND table2.versendet = '0000-00-00 00:00:00'
");
$stmt->execute([$scanned_number]);
$result = $stmt->fetch();
if ($result) {
?> the scanned number matches the given parameter
<?php
$sql = "UPDATE table2 SET versendet = date('Y-m-d H:i:s') WHERE unique_code = $scanned_number";
$stmt = $pdo->prepare($sql);
$stmt->execute();
} else {
?> the scanned number don´t matches
<?php
}?>
And i very relieved, that this tool saved my time.
And as a learn experience, i can now look to the statement to understood how this works. Awesome!
If someone has a other solution, please let me know.
Thank you!

WHERE clause in MySQL for selecting all

I have a script in PHP, which selects data from a Mysql Database using Select & Where clause.
$lrn= "PU2017LN11K";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn ORDER BY LRN,Sr ASC ');
$stmt->bindParam(':crn',$lrn);
$stmt->execute();
Now how to script the code so that it selects from all the LRN, using WHERE LRN = :crn.
I tried:
$lrn= "*";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn ORDER BY LRN,Sr ASC ');
$stmt->bindParam(':crn',$lrn);
$stmt->execute();
But it didn't show any results!
It's easy to skip the WHERE clause if I want to show all results, but
the value of $lrn will be defined by the $_GET method.
The normal way of handling this would be:
$lrn= "*";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN = :crn OR :crn = \'*\' ORDER BY LRN, Sr ASC ');
Alternatively, you could use LIKE:
$lrn = "%";
$stmt = $user_home->runQuery('SELECT * FROM mcq WHERE LRN LIKE :crn ORDER BY LRN, Sr ASC ');
You want all rows, don't use a where clause. Alternatively, if you must use a where (something in your code or thinking/design requires it), then you can also say something like "where 1" (like the way phpMyAdmin does things all the time, for what ever reason).
Use this as your where clause:
WHERE LRN = CASE WHEN :crn = '*' THEN LRN else :crn END
That way when the supplied :crn is '*' you will get all records.

Fetch row with the highest id column value [duplicate]

This question already has answers here:
Select the most recent 5 rows based on date
(2 answers)
Closed 2 years ago.
I would like to reuse a query with concatenation but It seems not working.
I have this for counting rows (working):
$q = $db->prepare("SELECT id, image_date, image_link, image_name, image_category FROM image WHERE image_date < NOW() AND image_category= :category";
$q->bindValue(':category', $category, PDO::PARAM_STR);
$q->execute();
$row = $q->fetchColumn();
And I would like to concatenate with that to use data (not working):
$q .= " ORDER BY id DESC LIMIT :limit");
$q->bindValue(':limit', 1, PDO::PARAM_INT);
$q->execute();
I've also test with that form but not working :
$q=$q. " ORDER BY id DESC LIMIT :limit");
The problem with PDO is that you have to prepare a query before you can bind anything, and once prepared, a query obviously cannot be extended anymore.
Besides, your first query does anything but count. So the simpler the better - just run two separate queries without concatenation
$q = $db->prepare("SELECT count(*) FROM image WHERE image_date < NOW() AND image_category= ?";
$q->execute([$category]);
$count = $q->fetchColumn();
And then
$q = $db->prepare("SELECT id, image_date, image_link, image_name, image_category
FROM image WHERE image_date < NOW() AND image_category= ? ORDER BY id DESC LIMIT ?";
$q->execute([$category, $limit]);
$rows = $q->fetchall();
You need to append the second part to the SQL string,
but not to the Prepared Statement variable $q.
$sql = "SELECT id, image_date, image_link, image_name, " .
"image_category FROM image WHERE image_date < NOW() " .
"AND image_category= :category ORDER BY id DESC LIMIT :limit";
$q = $db->prepare($sql);
$q->bindValue(':category', $category, PDO::PARAM_STR);
$q->bindValue(':limit', 1, PDO::PARAM_INT);
$q->execute();
$row = $q->fetchColumn();

Unable to run named placeholder for order by ASC in php pdo

I am new to PHP PDO and trying to use named placeholder at the place of ORDER BY ASC. Sometime in simple query page this run very successfully but unable to run in the following query:
PHP CODE IS:
$price_sort = "ASC";
$keyword = "samsung glaxy";
$limit = 0;
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price :order
LIMIT :limit,25");
$query->bindValue(":keyword",$keyword);
$query->bindValue(":order",$price_sort);
$query->bindValue(":limit", $limit, PDO::PARAM_INT);
$query->execute();
When I remove placeholder :order with ASC this run and gives result but when I use this placeholder, I get empty result.
For Fetching data or to show fetched result I am using
while ($row = $query->fetch(PDO::FETCH_ASSOC)) :
extract($row);
echo "$name";
endwhile;
What I am doing wrong and How I can use many named placeholder in query at different places?
You should not bind ASC/DESC in prepared statement. Parameters are automatically quoted, and ASC/DESC shouldn't be quoted. this is the same reason that table and column names can't be parameters.
Instead you can do like that
$sql_query = "SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, price "
if($price_order == 'ASC'){
$sql_query .= " ASC "
}else{
$sql_query .= " DESC "
}
$sql_query .= " LIMIT :limit,25 "
$query = $db->prepare($sql_query);
Refer How bindValue in LIMIT
Refer pdo binding asc/desc order dynamically
Also do not try to use the same named parameter twice in a single SQL statement, for example
<?php
$sql = 'SELECT * FROM some_table WHERE some_value > :value OR some_value < :value';
$stmt = $dbh->prepare($sql);
$stmt->execute( array( ':value' => 3 ) );
?>
...this will return no rows and no error -- you must use each parameter once and only once. Apparently this is expected behavior (according to this bug report: http://bugs.php.net/bug.php?id=33886) because of portability issues.
This one solved this question by replacing the price_sort variable value with price ASC and removing the price before the placehoder :order
as:
$price_sort = "price ASC";
and the query is as:
$query = $db->prepare("SELECT *, MATCH(title) against (:keyword) as 'relevence'
FROM view_store_items_grid
WHERE MATCH(title) against(:keyword)
ORDER BY relevence DESC, :order
LIMIT :limit,25");
this solved my question with the help of answer of #tamil
Thank you

php MySQL query not returning anything

I'm not sure exactly how to explain what the query does, however the problem isn't entirely with how it's set up, because it does work, in another instance, when I use it as an array, however it's not working when I use it with mysql_fetch_assoc(), so here is what my original query is(not the one im having trouble with):
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC
what this does is selects the last 3 comments on a post, then orders them in another way (so they show up in the correct order, old to new) Now this is the query for echoing out the array of comments directly.
But now what I want to do, is to just get the first id out of the 3 comments.
here's what I have tried to do (and by the way, this query DOES work, when i replace my previous query to echo out the results in an array, but i need to get just the id for use, i don't want an array):
$previousIDq = mysql_fetch_assoc(mysql_query("
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1"));
$previousID = $previousIDq['id']; //this doesn't return the id as I want it to.
Your problem may be that there are no matching rows.
Also, I think you could also improve your query to this:
SELECT * FROM comments WHERE postID='$id' AND state='0' ORDER BY id DESC LIMIT 2,1
But as others say, use PDO or MySQLi, and with prepared statements. And don't SELECT * ever.
try a var_dump($previousID) to see what you get
It is probably giving you back an object, and you need to get your id from that object
You script is too condensened for error handling, let alone debugging
$mysql = mysql_connect(...
$query = "
SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1
";
$result = mysql_query($query, $mysql);
if ( !$result ) { // query failed
die('<pre>'.htmlspecialchars(mysql_error($mysql)).'</pre><pre>'.htmlspecialchars($query).'</pre>');
}
$previousIDq = mysql_fetch_assoc($result);
if ( !$previousIDq ) {
die('empty result set');
}
else {
$previousID = $previousIDq['id'];
}
You need to separate your code to be able to debug
$query = "SELECT * FROM
(SELECT * FROM comments
WHERE postID='$id' AND state='0'
ORDER BY id DESC LIMIT 3
) t ORDER BY id ASC LIMIT 1";
$result = mysql_query($query);
echo mysql_error(); //what eror comes out here
while($previousIDq = mysql_fetch_assoc($result))
{
print ($previousIDq['id']);
}
NOTE: mysql_* is depreciated, upgrade to mysqli or PDO
Please stop using mysql_ functions to write new code, it is being deprecated. Use mysqli_ or PDO functions (mysqli below).
Bind your parameters to prevent SQL injection
Always use a column list (don't use SELECT *)
If you're returning > 1 row, use a while loop
mysqli_ solution
$link = mysqli_connect("localhost", "user_name", "password", "stock");
if (mysqli_connect_error()) {
die('Connect Error (' . mysqli_connect_errno() . ') ' . mysqli_connect_error());
}
$stmt = mysqli_prepare($link, "SELECT t.id FROM
(SELECT id FROM comments
WHERE postID = ? AND state = 0
ORDER BY id DESC
LIMIT 3) t
ORDER BY id ASC");
mysqli_bind_param($stmt, 's', $id) or die(mysqli_error($dbh));
$result = mysqli_stmt_execute($stmt) or die(mysqli_error($link));
while($row = mysqli_fetch_assoc($result)) {
echo $row[id];
}
mysqli_close($link);
mysql_ solution
$stmt = "SELECT t.id FROM
(SELECT id FROM comments
WHERE postID = $id AND state = 0
ORDER BY id DESC
LIMIT 3) t
ORDER BY id ASC";
$result = mysql_query($stmt) or die(mysql_error());
$row = mysql_fetch_assoc($result);
while($row = mysql_fetch_assoc($result)) {
echo $row[id];
}

Categories