I've got a table with some columns. I want to filter some records using two of them, the one with INT type and second with DATETIME type. I'm using PHP PDO extension to connect with database and make some queries.
I'm trying to get the records from my table where datetime field is lower then given date, f.e.
<?php
$date = date("Y-m-d");
$this->db->query("SELECT * FROM `" . DB_PREFIX . "fanpage` WHERE `flag_warning` = ? AND DATE(`update_date`) < ?", array(1, $date));
?>
This returns NULL, but when I paste the same query into the phpMyAdmin window it shows me proper records. What is the problem?
Edit:
Fragment from query function:
public function query($sql, $params = array())
{
$result = array();
$result['query'] = $this->pdo->prepare($sql);
$result['query']->execute($params);
$this->lastResult = $result['query'];
unset($result['query']);
}
No need for the prepared statements at all
WHERE flag_warning = 1 AND update_date < CURDATE()
Use
$sqlStatement = $this->db->prepare("SELECT * FROM `" . DB_PREFIX . "fanpage` WHERE `flag_warning` = ? AND `update_date` < CURDATE()");
$this->db->execute(array(1));
$result = $sqlStatement->fetchAll(PDO::FETCH_ASSOC);
Now $result has what you need.
I've changed the column name to date_time_upd and it works right now, I think it's bug or something, maybe someone can explain that?
Edit:
Okay, I've figured it out. There was a fragment of code that checked for occurrence of the "UPDATE, DELETE OR INSERT" word in the query, and if there was a word like that the query result was not fetched. I've changed that to search for SELECT word, now everything is okay.
Related
I have fields id and date defined as VARCHAR(16)
When I do this query:
SELECT *
FROM `members`
WHERE `id` = '4412040999876'
AND `date` = '201706054783'
I get no results.
When I do it like this:
SELECT *
FROM `members`
WHERE `id` = 4412040999876
AND `date` = 201706054783
Note - without the quotes - I get the result I am expecting.
EDIT: Here is the code used - I am not manually adding quotes. CI's DB class is adding them.
public function get_member_match($id, $mem, $field = 'name')
{
$sql = "
SELECT *
FROM `members`
WHERE `id` = ?
AND `" . $field . "` = ?
";
$sql_array = array($id, $mem);
$q = $this->db->query($sql, $sql_array);
return $q->result_array();
}
And I call this function as:
$this->members_model->get_member_match($id, $date, 'date');
I output the query, and the variables are matched correctly, no errors, only the quotes.
Any idea why? I never had this problem before. Working on CodeIgniter 3 using Query Builder.
EDIT2: Summary of findings so far:
Localhost (MySQL 5.6.24) works, server (MySQL 5.5.55-0+deb7u1) doesn't.
The problem occurs in my code and in PHPMyAdmin on the server but works locally, so I eliminate a code issue.
The show variables like 'char%' query shows all character set settings identical on local and on the server.
Database and fields have the same encoding on both server and local.
Does not seem to be a casting issue as many of the comments suggest, as the problem is not present on localhost, only on the server, unless the server has config or other issues.
...?
id might be defined as integer in your database. To match against integer fields you do not need to use quotes. Quotes are used when you match against string or text fields.
This should cast it back from the codeigniter's auto cast:
SELECT *
FROM `members`
WHERE `id` = '4412040999876'
AND `date` = '201706054783'
SELECT *
FROM `members`
WHERE CAST(`id` as INTEGER) = '4412040999876'
AND `date` = '201706054783'
Try to use this
$this->db->from('members');
$this->db->where('id',$id);
$this->db->where($field,$mem);
$q = $this->db->get();
return $q->result_array();
It's because the quotes imply that it is a string, whereas id field is an integer and must be written without quotes.
Same for date. Internally date is stored as an integer but is able to convert string into dates as long as they have an appropriate format
How i find the Last Updated Values inside the all the table field in a given Database?
Search results for "%2015-07-08%" at least one of the words:
Its not impossible, but its not trivial either. I don't think that there is an easy way to do this with SQL alone (I assume that you use mySQL, but you haven't really specified what kind of database you are using).
One way to do it is make a script that uses INFORMATION_SCHEMA tables to find the relevant tables and columns to search through, then iterate those in PHP and execute queries that search those columns and tables.
Edit:
Just for the sake of doing it I made a small example of what i mean, this code uses PDO:
function findAll($search_str, $database, $types = ['tinytext','blob','varchar','text','longblob']){
global $pdo;
foreach($types as &$t){
$t = "'" . $t . "'";
}
$types = implode(',',$types);
$s = $pdo->prepare("
SELECT TABLE_NAME, COLUMN_NAME
FROM INFORMATION_SCHEMA.columns
WHERE
TABLE_SCHEMA = :database
AND DATA_TYPE IN ($types)
");
$s->bindValue(':database', $database);
$s->execute();
$results = [];
foreach($s->fetchAll(\PDO::FETCH_ASSOC) as $column){
$search = $pdo->prepare("SELECT * FROM $database.${column['TABLE_NAME']} WHERE ${column['COLUMN_NAME']} LIKE :search_str");
$search->bindValue(':search_str', $search_str);
$search->execute();
$result = $search->fetchAll(\PDO::FETCH_ASSOC);
if(count($result))
$results[$column['TABLE_NAME']] = isset($results[$column['TABLE_NAME']])
? array_merge(
$results[$column['TABLE_NAME']],
$result
)
: $result;
}
return $results;
}
Example of usage:
findAll('%foobar%','my_database');
findAll('%2015-07-08%','my_database',['date','datetime','timestamp']); //Only search date types...
How about checking the latest value of the key column e.g. in an column with auto increment you check the highest value? This is just a suggestion though while assuming you have such a column. The other idea would be to add a column with a timestamp data type so that you can update it automatically during inserts or updates.
Using the code below, I'm having trouble checking whether a specified date exists in a MySQL 'date' column.
$data = array(1367971200);
$s=$dbh->prepare("
SELECT DISTINCT
`date`
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?
");
if ($s->execute($data)) {
if ($s['date'] == null) {
return false;
}
return true;
}
It's returning false, despite the fact that I can see the date '2013-05-08' displayed in phpMyAdmin.
The table itself contains 70+ entries for that date. It always will do, if it contains any at all, but I just want to know whether it exists or not at this stage.
The date field is a MySQL 'date' type. I'm suspecting that the bug is in my structuring of the PDO calling of the query.
UPDATE
Updated $r['date'] to `$s['date']. I suspect that I still have an issue with the structure of that, but probably need to fix the query so that it gives us results before focusing on this.
Also tried running the query against the database directly and got an empty resultset, despite being able to see that the target date exists. Still baffled!
Try this
$data = array(1367971200);
$s=$dbh->prepare("
SELECT COUNT(`date`) as c_date
FROM
`report_coa_bal_hist`
WHERE
UNIX_TIMESTAMP(`date`) = ?");
if ($s->execute($data)) {
$result = $s->fetch(PDO::FETCH_ASSOC);
if ($result['c_date'] > 0) {
return false;
}
return true;
}
You can't select a whole day with UNIX timestamps because of their more accurate nature (i.e. seconds), you would need the textual version:
$data = array(date('Y-m-d', 1367971200));
$stmt = $dbh->prepare("SELECT COUNT(*)
FROM `report_coa_bal_hist`
WHERE `date` = ?
");
$stmt->execute($data);
$count = current($stmt->fetchAll(PDO::FETCH_COLUMN, 0));
return $count > 0;
Take note of any timezone differences between the server that runs your script and the database server itself.
there are many flaws with your code, not one:
format of the value you are checking
way you are checking in SQL
the way you are getting result
So, the code have to be
$data = array('2013-05-07');
$sql = "SELECT 1 FROM report_coa_bal_hist WHERE `date` = ? LIMIT 1";
$stm = $dbh->prepare($sql);
$stm->execute($data);
return $stm->fetchColumn();
This works:
$sql = "SELECT id
FROM `users`
WHERE `account_status` = '" . $i . "'";
$query = $this->db->query($sql);
var_dump($query->num_rows());
But this doesn't:
$sql = "SELECT COUNT(*)
FROM `users`
WHERE `account_status` = '" . $i . "'";
$query = $this->db->query($sql);
var_dump($query->num_rows());
How to do a num_rows on a COUNT(*) query? Also is doing it the 2nd way any better performance wise?
Doing a COUNT(*) will only give you a singular row containing the number of rows and not the results themselves.
To access COUNT(*) you would need to do
$result = $query->row_array();
$count = $result['COUNT(*)'];
The second option performs much better since it does not need to return a dataset to PHP but instead just a count and therefore is much more optimized.
In CI it's really simple actually, all you need is
$this->db->where('account_status', $i);
$num_rows = $this->db->count_all_results('users');
var_dump($num_rows); // prints the number of rows in table users with account status $i
$query->num_rows()
The number of rows returned by the query. Note: In this example, $query is the variable that the query result object is assigned to:
$query = $this->db->query('SELECT * FROM my_table');
echo $query->num_rows();
num_rows on your COUNT() query will literally ALWAYS be 1. It is an aggregate function without a GROUP BY clause, so all rows are grouped together into one. If you want the value of the count, you should give it an identifier SELECT COUNT(*) as myCount ..., then use your normal method of accessing a result (the first, only result) and get it's 'myCount' property.
As per CI Docs we can use the following,
$this->db->where('account_status', $i); // OTHER CONDITIONS IF ANY
$this->db->from('account_status'); //TABLE NAME
echo $this->db->count_all_results();
If we want to get total rows in the table without any condition, simple use
echo $this->db->count_all_results('table_name'); // returns total_rows presented in the table
it's my way of solving the above given question
model
$this->db->select('count(id) as ids');
$this->db->where('id', $id);
$this->db->from('your_table_name');
thanks
This will only return 1 row, because you're just selecting a COUNT(). you will use mysql_num_rows() on the $query in this case.
If you want to get a count of each of the ID's, add GROUP BY id to the end of the string.
Performance-wise, don't ever ever ever use * in your queries. If there is 100 unique fields in a table and you want to get them all, you write out all 100, not *. This is because * has to recalculate how many fields it has to go, every single time it grabs a field, which takes a lot more time to call.
I'd suggest instead of doing another query with the same parameters just immediately running a SELECT FOUND_ROWS()
$list_data = $this->Estimate_items_model->get_details(array("estimate_id" => $id))->result();
$result = array();
$counter = 0;
$templateProcessor->cloneRow('Title', count($list_data));
foreach($list_data as $row) {
$counter++;
$templateProcessor->setValue('Title#'.$counter, $row->title);
$templateProcessor->setValue('Description#'.$counter, $row->description);
$type = $row->unit_type ? $row->unit_type : "";
$templateProcessor->setValue('Quantity#'.$counter, to_decimal_format($row->quantity) . " " . $type);
$templateProcessor->setValue('Rate#'.$counter, to_currency($row->rate, $row->currency_symbol));
$templateProcessor->setValue('Total#'.$counter, to_currency($row->total, $row->currency_symbol));
}
I am new to PHP and MYSQL so this should be a pretty basic question.
I am querying a mysql database and getting three fields into an array. One of the fields type is datetime, but with my current query, it is being captured as a string.
This is my code:
$myquery = mysql_query ("SELECT id,text,when FROM messages ORDER BY cuando DESC");
$nrows = mysql_num_rows ($myquery);
for ($i = 0; $i < $nrows; $i++) {
$row = mysql_fetch_assoc ($myquery);
$when = $row["when"];
I've been googling and I think i have to use the AS operator in my query, but I dont' know how. How can I do this? If possible, just by changing the query...
Thanks!
in PHP: $when = strtotime($row["when"]);
in mySQL: SELECT id, text, UNIX_TIMESTAMP( when ) AS when FROM...
If you want a unix timestamp, you can either do it in your query or in php.
In your query:
$myquery = mysql_query ("SELECT id,text,UNIX_TIMESTAMP(when) FROM messages ORDER BY when DESC");
in PHP:
$when = strtotime($row['when']);
Edit: WHEN being a reserved MySQL keyword, this query will give an error. Use something else for your date field.