Pagination with custom query
Fri, 08/07/2009 - 04:20
Does the pagination of datagrid works with custom SQL queries too? I got a datagrid that has a complex SQL involving data aggregation from 5 different tables and I think it will be extremely painful to use QQuery. Please help.
Thanks.

Definitely, but you control what's displayed in the grid, so you will need to alter your raw SQL to make use of the QDataGrid's LimitInfo and PageNumber properties to build your SQL query.
Thats cool!!! Can you give me an example. I have done half the thing, I mean from the datagrid side, got the paginator defined and got the record count in Bind method. Now don't know how to modify the query to include QDataGrid's LimitInfo and PageNumber properties.
Thanks a lot.
We really need an example for this, it comes up all the time.
I think this may work, depending on your DB:
$intOffset = ($dtgPeople->PageNumber - 1) * $dtgPeople->ItemsPerPage;$strLimitInfo = $intOffset . ',' . $dtgPeople->ItemsPerPage
$sql .= $this->objDatabase->SqlLimitVariablePostfix($strLimitInfo);
Depending on your DB, you may have to use SqlLimitVariablePrefix instead, and insert it next to Select.
It worked if I use:
<?php$objDbResult = $objDatabase->Query($strQueryAvl. " limit ".
$this->dtgAvailabilities->ItemsPerPage." offset "
. $intOffset );
?>
and not when any of SqlLimitVariablePrefix or SqlLimitVariablePostfix. The latter gives an error and the former does not produce intended result.
Any suggestions? I would also like to implement sorting onto this.
Thanks.
I solved the sorting thing by using the following parameters of the datagrid and modifying the select query based on them.
<?php$this->dtgView->SortColumnIndex
?>
<?php$this->dtgView->SortDirection
?>
Thanks for all the help, VexedPanda.
+ 1 vote for: Please add this to the examples.
Datagrid pagination with custom queries with filtered datagrid and standard datagrid
:)
Agreed, meetsang, mind posting your bind function? I don't think anyone that has gotten this working has ever posted their complete code.
Here is the whole code: http://pastebin.com/m7372a75
Please don't mind the tidyness of the code. I am very bad in writing neat code.
Thanks.
I just took a look, and I don't see any $objDatabase->SqlVariable() calls. These are very important in order to avoid SQL injection attacks. With your code, any random person could come in and delete your entire database using just that form.
eg: Try entering this in txtClientName:
%"; insert into coavailableshifts (ContractorID, ClientID, TradingName, Date) values (1,1, 'hacked', '2009-08-10'); --
Thanks Vexed Panda, I will implement that into the custom query.
Could you also let me know of any other security steps I need to take up with QCubed framework?
Thanks a lot.
No, that's about it. QCubed takes care of pretty much everything for you. It's just when you skip the use of QCubed (in this case QQ) that you have to start manually filtering user input again.
Could the code for this custom query pagination fix please be re-posted? The paste bin code is no longer available.
Thanks!
Also - it'd be great if someone could put together a very simple example for http://examples.qcu.be that illustrates this.
Sorry to rebirth this old topic but.
I'm still in trouble with pagination. does any have a fullcode to implement qdatarepeater and custom sql (onto multiple table) pagination ?
I managed to limit data on page but... the pagination shows me only one page where it should give me a lot more.
Any idea ?
i've something like this :
$intOffset = ($this->dtr->PageNumber - 1) * $this->dtr->ItemsPerPage;
$customSql = "SELECT *
FROM invoice
JOIN user u
ON u.id = invoice.user_id
WHERE invoice.date < NOW()
ORDER BY invoice.date";
$customSql .="LIMIT ".$this->dtr->ItemsPerPage." OFFSET "
. $intOffset;
$objDatabase = QApplication::$Database[1];
$invoice= $objDatabase->Query($customSql);
while($row = $invoice->FetchArray()) $resArray[] = $row;
$this->dtr->TotalItemCount = count($invoice);
$this->dtr->DataSource = $resArray;
I guess the problem is TotalItemCount value as it'll be always equals to the number of rows fetched ... so display one page is a normal behaviour.
The problem is that i have to run again the query without the limit clause to get the numbers of results.
This raises numbers of questions to me :
We have 1 query to fetch the limited rows
We have 1 query to count all rows
We have one looping to create a $resArray used as DataSource
One other loop handled by the repeater to run across the results
That sounds too much to me.
I think i'm doing something bad somwhere but what ?
Also i tried to give the result of ->Query straight as DataSource but didn't worked...
Thanks in advance for any reply.
kent
Hi,
Try using SQL_CALC_FOUND_ROWS function:
<?php$invoice= $objDatabase->Query('
SELECT SQL_CALC_FOUND_ROWS * FROM tbl_name LIMIT 10
');
$totalItemCount = $objDatabase->Query('
SELECT FOUND_ROWS()
');
?>
this way you have both the result set and the total number of rows in one query.