PHP - using PDO with a date field not working - php

so this has been driving me nuts for the last two hours...
$sql = 'SELECT * FROM master_rets_table
WHERE listing_entry_timestamp > "2014-04-01 00:00:00"
ORDER BY listing_price DESC';
}
$this->stm = $this->prepare($sql);
$this->stm->execute();
Running this query outside PDO in Navicat works fine ( i get 17 records), but no matter how I try to change this up, it is simply not working in PDO. I'm using this same code for lots of PDO queries that do not use a date constraint, and they all work wonderfully.
fyi, listing_entry_timestamp is a DateTime field
EDIT - here is the whole code block
if ($this->city != "" ) {
$sql = 'SELECT * FROM master_rets_table
WHERE city = '.$this->city.'
ORDER BY listing_price DESC';
}
else if ($this->subdiv != ""){
$sql = 'SELECT * FROM master_rets_table
WHERE subdivision REGEXP '.$this->subdiv.'
ORDER BY listing_price DESC';
}
else if ($this->date_from != "") {
$sql = "SELECT * FROM master_rets_table WHERE (listing_entry_timestamp > '2014-04-01') ORDER BY listing_price DESC";
}
$this->stm = $this->prepare($sql);
$this->stm->execute();
$this->rows= $this->stm->fetchAll(PDO::FETCH_ASSOC);
$this->count = $this->stm->rowCount();
$this->rowIdx = 0;
it is working fine for the other two cases...it seems to have something to do with the datetime field or something.
EDIT [SOLUTION] - Well, it turns out that the live data wasn't being pushed to the development server and i was testing it in Navicat against the live data, so the query looking for yesterday's data couldn't find anything.

PDO has nothing to do with date fields.
It works with dates all right.
So, look for bugs in your code/data base/environment/whatever.
My bet for the different databases. One you connect with navicat contains 17 records to match and one you connect with PDO contains nones.
Second guess is some wrong code in your db class.
What is driving me nuts is pointless suggestions with wild guesses.
O.K.
mysql
mysql> create table so_again(d datetime);
Query OK, 0 rows affected (0.23 sec)
mysql> insert into so_again values (now());
Query OK, 1 row affected (0.08 sec)
mysql> select * from so_again where d > '2014-04-01 00:00:00';
+---------------------+
| d |
+---------------------+
| 2014-04-02 00:23:16 |
+---------------------+
1 row in set (0.02 sec)
PHP
$sql = 'select * from so_again where d > "2014-04-01 00:00:00"';
$stm = $pdo->prepare($sql);
$stm->execute();
$stm = $stm->fetchAll();
var_dump($stm);
ouptut
array(1) {
[0]=>
array(1) {
["d"]=>
string(19) "2014-04-02 00:23:16"
}
}
It works.
at least with raw PDO.
there is no problem with SQL
there is no problem with PDO
there is no problem with date
there is no problem with quotes (as long as we take 17 returned results for granted. however, in ANSI mode they will cause an error)
There can be only problem with your own code/data/input

Try this:
$sql = "SELECT * FROM master_rets_table WHERE listing_entry_timestamp > :date ORDER BY listing_price DESC";
$statement = $this->prepare($sql);
$statement->bindParam (":date", "2014-04-01 00:00:00");
$statement->execute();

The only two things that come to my mind are that you might have some kind of casting error in the date parameter, or a logic path error. I also noticed that you treat $city as if it was a string, yet you do not quote it.
Try with:
if ($this->city != "" ) {
$where = 'city = ?';
$match = $this->city;
} else if ($this->subdiv != "") {
$where = 'subdivision REGEXP ?';
$match = $this->subdiv;
} else if ($this->date_from != "") {
$where = 'listing_entry_timestamp > ?';
$match = 20140401;
} else {
trigger_error("No search", E_USER_ERROR);
}
$sql = "SELECT * FROM master_rets_table WHERE {$where} ORDER BY listing_price DESC";
$this->stm = $this->prepare($sql);
$this->stm->execute(array($match));
$this->rows = $this->stm->fetchAll(PDO::FETCH_ASSOC);
$this->count = $this->stm->rowCount();
$this->rowIdx = 0;
This should both supply a 'recognizable' parameter to PDO and ensure that $sql is indeed populated.
Another possibility
You say,
$city is preformatted with PDO::quote()...thats an old habit of mine
If it were so, let's suppose that $this->city is initially empty.
Then PDO::quote would make it into an empty quoted string: i.e. a pair of quote marks with nothing inside.
Then, the comparison $this->city != "" would always return true, because city is not "", but "''".
And so the SQL would run a different query from what you'd expect.

can you tell me the output when you execute this modified query:
$sql = 'SELECT * FROM master_rets_table
WHERE (listing_entry_timestamp > :entry_date)
ORDER BY listing_price DESC';
}
$this->stm = $this->prepare($sql);
$this->stm->execute(array("entry_date"=>"2014-04-01 00:00:00"));

Related

What is going wrong with this query?

public function get_modno_sno($id)
{
$query = 'select a.model_no,a.serial_no,a.stock_id from tra_item_stock a where a.trans_id is NULL and a.model_no = '.$id.'
union
select a.model_no,a.serial_no,a.stock_id from tra_indent_issue_details_2 a where a.flag = 3 and a.model_no ='.$id;
$result = $this->db->query($query);
return $result->result();
}
When I run this query error displayed as:
column "kb234" does not exist
kb234 is character varying value passed to $id
You do not surround kb234 with quotes, so the database identifies it as a column name.
You could modify you code to include the quotes:
public function get_modno_sno($id)
{
$query = "select a.model_no,a.serial_no,a.stock_id from tra_item_stock a where a.trans_id is NULL and a.model_no = '$id'
union
select a.model_no,a.serial_no,a.stock_id from tra_indent_issue_details_2 a where a.flag = 3 and a.model_no = '$id'";
$result = $this->db->query($query);
return $result->result();
}
Note, however, that creating SQL queries by using string manipulation is a dodgy practice, that leaves your code vulnerable to SQL injection attacks. You should consider using a prepared statement.
.model_no ='.$id;
is missing an ' at the end for the union query

Pass the parameter into query

I'm new in php and PDO. I just wondering how to pass the parameter into my query,
I already assign $a="January 2010 Semester"; and to pass to my query. But when i echo the query, it display like this.
SELECT Nama,Intake,matricNo, FROM VMESubjectGrade where Intake="$a" GROUP BY Nama
It Should be display like this
SELECT Nama,Intake,matricNo, FROM VMESubjectGrade where Intake="January 2010 Semester" GROUP BY Nama
This is my code,
Hope can advise,
Special Thanks.
$a="January 2010 Semester";
mysql_select_db("school", $con);
$query2='SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake="$a"' ;
$query2testing = mysql_query($query2);
try {
$db = new PDO('mysql:host=localhost;dbname=school;charset=utf8', 'root', 'xxx');
} catch (PDOException $e) {
echo $e->getMessage();
}
//get the SubCodes
$stmt = $db->query('SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake="$a"');
$row_count = $stmt->rowCount();
//generate pivot sql statement
$sql = 'SELECT Nama,Intake,matricNo, ';
$dynamic_fields = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$dynamic_fields[] = $row['SubCode'];
$sql .= "MAX(CASE SubCode when '{$row['SubCode']}' then grade end) AS {$row['SubCode']}";
if ($row_count > 1) {
$sql .=',';
}
$row_count--;
}
$sql .= ' FROM VMESubjectGrade where Intake="$a" GROUP BY Nama ';
echo $sql;
THIS PROBLEM ALREADY SOLVE.
I know you think you've already solved the problem, but please read this!!
One of the main advantages to PDO is the ability to do parameterized queries, which will sanitize your database inputs. As you currently have it, you're vulnerable to SQL injection!
If someone passes a variable that you use in the query, and you don't sanitize it, you will end up in big trouble. Suppose $a was set to "; DROP TABLE VMESubjectGrade;--. What does your query become? It becomes this:
SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake=""; DROP TABLE VMESubjectGrade;--"
The day someone tries something like this will be a very bad day for you, unless you properly sanitize your database inputs.
Try doing your queries like this:
$query = 'SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake = :a';
$stmt = $db->prepare($query);
$stmt->execute(array(':a' => $a));
This will pass the parameter in to the query and sanitize the variable in case it actually comes from user input.
:a acts as a placeholder for a parameter in your query and you assign the value of it when you execute.
you should concact that string into query like this
echo $query2='SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake='.$a.'';
$query2testing = mysql_query($query2);
output will be like this-> SELECT DISTINCT(SubCode) FROM VMESubjectGrade where Intake=January 2010 Semester

Returning multiple results when only one present in DB

Alrighty, so this code has been giving me trouble for the past day or so. All of its duties are working perfectly fine, save for the Tax query. (at least thats the only one thats giving me trouble that i can tell of)...
as far as i can tell; the code is giving me trouble because their are multiple TUID and UID's that are the same, but don't go to the same user, (EG an ID that == 1 might be User1 or it might be Group1).
I'm not asking for you guys to fix this code, (It seems everytime i post here, someone says 'oh you just want us to fix your code and blah blah blah blah') I'm just curious if anybody has a good work around for this?
I'm getting duplicate rows returned to the query;
this is what the query returns: http://gmz1023.com/rowline.PNG
{
$sql = "SELECT type FROM bank_transaction LIMIT 25";
$que = $this->db->prepare($sql);
$que->bindParam('uid', $uid);
try{
$que->execute();
ob_start();
if($que)
{
$id = '1';
$transaction = '';
while($row = $que->fetch())
{
/* This is the tricky bit; for each type that is returned, we start another query and pull up that data.<
/* This may need to be turned into seperate functions later on. however, for now, keep trying to figure out how to get the code to work,
/* There's nor eason why it shouldn't work, as its simple as hell. and yet we keep getting multiple rows in the table.
*/
if($row[0] == 'govt')
{
$sql = "SELECT tuid, uid, balance FROM bank_transaction WHERE type = :type AND uid = :uid";
$querty1 = $this->db->prepare($sql);
$type = 'govt';
$querty1->bindParam('type', $type);
$querty1->bindParam('type', $row[0]);
$querty1->bindParam('uid', $uid);
try {
if($querty1->execute())
{
$info = $querty1->fetch();
$to = parent::getUsername($info[0]);
$from = parent::getStoryName($info[1]);
$balance = $info[2];
$transaction .= "<tr><td>{$id}</td><td>{$from}</td><td>{$to}</td><td>{$balance}</td><td>{$row[0]}</td></tr>";
$querty1->closeCursor();
}
}catch(PDOException $e) { echo $e->getMessage();}
}
if($row[0] == 'business')
{
$sql = "SELECT tuid, uid, balance, date FROM bank_transaction WHERE type = :type AND tuid = :uid OR uid = :uid";
$querty1 = $this->db->prepare($sql);
$type = 'business';
$querty1->bindParam('type', $type);
$querty1->bindParam('type', $row[0]);
$querty1->bindParam('uid', $uid);
try {
if($querty1->execute())
{
$info = $querty1->fetch();
$to = $info[0];
$from = $info[1];
$balance = $info[2];
$date = $info[3];
$transaction .= "<tr><td>{$id}</td><td>{$from}</td><td>{$to}</td><td>{$balance}</td><td>{$row[0]}</td><td>{$info[3]}</tr>";
$querty1->closeCursor();
}
}catch(PDOException $e) { echo $e->getMessage();}
}
if($row[0] == 'tax')
{
$sql = "SELECT tuid, uid, balance, date FROM bank_transaction WHERE tuid = :tuid AND type = :type ;";
$querty = $this->db->prepare($sql);
$type = 'tax';
$uid = '2';
$querty->bindParam('type', $type);
$querty->bindParam('tuid', $uid);
try {
if($querty->execute())
{
$info = $querty->fetch();
$to = parent::getStoryName($info[0]);
$from = parent::getUsername($info[1]);
$balance = $info[2];
$transaction .= "<tr><td>{$id}</td><td>{$from}</td><td>{$to}</td><td>{$balance}</td><td>{$row[0]}</td><td>{$info[3]}</tr>";
$querty->closeCursor();
}
}catch(PDOException $e) { echo $e->getMessage();}
}
elseif($row[0] == 'personal')
{
$sql = "SELECT tuid, uid, balance FROM bank_transaction WHERE type = :type AND uid = :uid OR tuid = :uid";
$querty = $this->db->prepare($sql);
$type = 'personal';
$querty->bindParam('type', $type);
$queryt->bindParam('uid', $uid);
try {
if($querty->execute())
{
$info = $querty->fetch();
$to = $info[0];
$from = $info[1];
$balance = $info[2];
$transaction .= "<tr><td>{$id}</td><td>{$from}</td><td>{$to}</td><td>{$balance}</td><td>{$row[0]}</td></tr>";
$querty->closeCursor();
}
}catch(PDOException $e) { echo $e->getMessage();}
}
$id = $id +1;
}
return $transaction;
ob_end_clean();
}
else
{
echo "ERROR!";
}
}catch(PDOException $e) { echo $e->getMessage(); }
}
The Database
tid int(11) No None AUTO_INCREMENT
uid int(11) No None
tuid int(11) No None
balance int(11) No None
type enum('personal', 'govt', 'business', 'tax') latin1_swedish_ci No date datetime
The tax query has a semicolon at the end. It's likely that this causing MySQL to throw an error.
But the entire code example is bizarre. The displayed $id value isn't from the database, it's a loop counter for the rows fetched from first query.
SELECT type FROM bank_transaction LIMIT 25
For each row returned, a check is performed on the value returned for "type", and depending on the value, one of four other queries is executed. The queries are all similar:
"govt"
SELECT tuid
, uid
, balance
, date
FROM bank_transaction
WHERE type = :type
AND tuid = :uid
OR uid = :uid
"business"
SELECT tuid
, uid
, balance
, date
FROM bank_transaction
WHERE type = :type
AND tuid = :uid
OR uid = :uid
"tax"
SELECT tuid
, uid
, balance
, date
FROM bank_transaction
WHERE tuid = :tuid
AND type = :type
"personal"
SELECT tuid
, uid
, balance
FROM bank_transaction
WHERE type = :type
AND uid = :uid
OR tuid = :uid
There's some potential problems with the precedence of AND and OR in some of those queries, and there's also a potential problem with PDO and referencing the same named bind variable more than once (but this "bug" may have been addressed in a more recent version of PDO.)
And the bindParam calls specify the named bind parameter without the leading colon, which is odd. I've never seen that before.
I think the bigger issue with the code is that each time through the outermost loop (it does manage to successfully increment the $id value each time through). But for each type, it executes an identical SQL statement, with identical bind values. And it's a nearly guaranteed that MySQL is returning the same set of rows, in the same order, each time the query is executed.
But only the first row is fetched and processed.
I apologize if this is blunt, but...
This looks as if someone threw a whole pile of code at the problem, without actually having a good conceptual understanding of what needs to be done, and without thinking through a workable algorithm.
The problems with this code are lot bigger than syntax issues.
The outermost query that gets type from the database doesn't look like it has any purpose, except to limit the number of rows returned. (I'm a little surprised there aren't 25 rows in the result; I can only guess that there are either actually 4 rows in the table, or more likely, that query is returning more than 4 rows, but the fifth row returned has type='tax', which is causing the "tax" query to be executed, which is causing a MySQL syntax error.
This code is not "simple" at all. It's overly complex, and unsurprisingly ineffective.
You could use GROUP BY to make selection unique:
SELECT tuid, uid, balance FROM bank_transaction WHERE type = :type AND uid = :uid GROUP BY uid

PHP PDO mySQL return null

The following code returns me people with similar telephone numbers. It works perfectly but when there are no numbers the function still returns information meaning that I cannot check hide a certain box if there are no other people with similar numbers.
THE FUNCTION
function getothers($tid,$criteria,$telephone,$telephone2,$elector){
global $dbh;
$tid = '-TID'.$tid;
$sql = "SELECT * FROM electors WHERE ((telephone > 0 AND telephone IN ('$telephone','$telephone2')) OR (telephone2 > 0 AND telephone2 IN ('$telephone','$telephone2'))) $criteria AND records NOT RLIKE '$tid' AND ID != '$elector' LIMIT 10";
$result = $dbh->query($sql);
return $result;
}
THE CALL
<?php $others = getothers($post['TID'],$post['criteria'],$elector['telephone'],$elector['telephone2'],$elector['ID']); ?>
THE LINE THAT DOES NOT WORK
<?php if(!$others){?>
$others still has something in it despite no results. I think I might be missing a line in y PDO. Any ideas?
The print_r
PDOStatement Object ( [queryString] => SELECT * FROM electors WHERE ((telephone > 0 AND telephone IN ('02085414023 ','')) OR (telephone2 > 0 AND telephone2 IN ('02085414023 ',''))) AND (this_vi_street = '' AND this_vi_telephone = '') AND (mosaic IN ('A01','A02','A03','A04','A05','A07','B11','C15','C16','C17','C18','H46','J52','K57','K58','K60') OR last_vi IN ('C','P')) AND postal_vote != 1 AND records NOT RLIKE '-TID1' AND ID != '13' LIMIT 10 )
As per the comments, a version using prepared statements:
function getothers($tid, $criteria, $telephone, $telephone2, $elector) {
global $dbh;
$stmt = $dbh->prepare("SELECT *
FROM electors
WHERE ((telephone > 0 AND telephone IN (:telephone, :telephone2))
OR (telephone2 > 0 AND telephone2 IN (:telephone, :telephone2)))
$criteria
AND records NOT RLIKE :tid
AND ID != :elector
LIMIT 10";
$stmt->execute(array(
':telephone' => $telephone,
':telephone2' => $telephone2,
':tid' => '-TID' . $tid,
':elector' => $elector
));
return $stmt->fetchAll();
}
There are still some bad points in this code:
Uses global to get the DB connection, this is overall bad application structure. You should probably use a class or pass $dbh as a regular argument into the function.
Concatenates $criteria into the prepared statement. Do you really need such dynamic conditions that you can't prepare a query for it without concatenating whole SQL blocks into it?
Doesn't necessarily address your actual problem of function returns.
Maybe do something like
$result = $dbh->query($sql);
if($result->rowCount()>0)
{
return $result;
}
return false;

Function to count MySQL rows using WHERE

am making function to count rows using "WHERE", but i get a mysql error
Warning: mysql_num_rows(): supplied argument is not a valid MySQL result resource in C:\AppServ\www\test\test\index.php on line 9
Unknown column '1' in 'where clause'
here is my function
function CountRows($table, $field = NULL, $value = NULL){
mysql_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD);
mysql_select_db(DB_NAME);
if($field != NULL && $value != NULL){
return mysql_num_rows(mysql_query("SELECT * FROM `".$table."` WHERE `".$field."` = `".$value."`"))or die(mysql_error());
}else{
return mysql_num_rows(mysql_query("SELECT * FROM `".$table."`"));
}
}
i've created this function to simplify counting rows mysql rows for banned members, inactive members etc, since all will be using WHERE
all help will be appreciated, thanks in advance
You should not connect to database each time you need to do a query.. Just keep a persistent connection or ideally use PDO.
Value should be enclosed with simple single quotes. This is probably what is getting you an error, as anything enclosed in backticks kind of quotes is considered a database/table/field name.
Use COUNT(*), it does not fetch all the database rows.
If value is possibly supplied by user, make sure that it is safe by escaping it with mysql_real_escape_string if not using PDO.
Without using PDO code would be:
mysql_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD);
mysql_select_db(DB_NAME);
function CountRows($table, $field = NULL, $value = NULL){
if ($field != NULL && $value != NULL) {
$query = "SELECT COUNT(*)
FROM `".$table."`
WHERE `".$field."` = '". mysql_real_escape_string($value) . "'";
} else {
$query = "SELECT COUNT(*) FROM `".$table."`";
}
$count = mysql_fetch_array(mysql_query($query));
return $count[0];
}
Backticks (`) are for enclosing table and column names. Don't wrap $value in them, just use single-quotes (').
Also, there's no reason you need to pull the full data set from the DB and count the rows in it. Just query for the count:
if($field != NULL && $value != NULL){
$cnt = mysql_fetch_assoc(mysql_query("SELECT COUNT(*) as cnt FROM `".$table."` WHERE `".$field."` = '".$value."'"))or die(mysql_error());
}else{
$cnt = mysql_fetch_assoc(mysql_query("SELECT COUNT(*) as cnt FROM `".$table."`"));
}
return $cnt['cnt'];
Additionally:
Do not connect/select database in the function. This should be done one time at the beginning of every page, no more (unless multiple connections are desired).
Do not SELECT * just so you can calculate the number of rows. Use MySQL's COUNT() function instead.
$result = mysql_query("SELECT COUNT(0) AS numRows FROM aTable");
$numRows = mysql_result($result, 0, 'numRows');
Do NOT use your function with user input without taking appropriate actions to secure yourself against SQL injection.

Categories