Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how to query sqlite for certain rows, i.e. dividing it into pages (perl DBI)

Tags:

sqlite

perl

dbi

sorry for my noob question, I'm currently writing a perl web application with sqlite database behind it. I would like to be able to show in my app query results which might get thousands of rows - these should be split in pages - routing should be like /webapp/N - where N is the page number. what is the correct way to query the sqlite db using DBI, in order to fetch only the relavent rows.

for instance, if I show 25 rows per page so I want to query the db for 1-25 rows in the first page, 26-50 in the second page etc....

like image 367
user1380641 Avatar asked Oct 22 '12 16:10

user1380641


People also ask

What is SQLite database explain with all queries and its syntax?

SQLite is an in-process library that implements a self-contained, serverless, zero-configuration, transactional SQL database engine. It is a database, which is zero-configured, which means like other databases you do not need to configure it in your system.

Does SQLite support offset?

SQLite Limit: In the LIMIT clause, you can select a specific number of rows starting from a specific position using the OFFSET clause. For example, “LIMIT 4 OFFSET 4” will ignore the first 4 rows, and returned 4 rows starting from the fifth rows, so you will get rows 5,6,7, and 8.


4 Answers

Using the LIMIT/OFFSET construction will show pages, but the OFFSET makes the query inefficient, and makes the page contents move off when the data changes.

It is more efficient and consistent if the next page starts the query at the position where the last one ended, like this:

SELECT *
FROM mytable
ORDER BY mycolumn
WHERE mycolumn > :lastvalue
LIMIT 25

This implies that your links are not /webapp?Page=N but /webapp?StartAfter=LastKey.

This is explained in detail on the Scrolling Cursor page.

like image 92
CL. Avatar answered Oct 02 '22 19:10

CL.


You should do something like this:

SELECT column FROM table ORDER BY somethingelse LIMIT 0, 25

and when the user clicks on page 2, you should do:

SELECT column FROM table ORDER BY somethingelse LIMIT 25, 50

and so on..

like image 40
rizidoro Avatar answered Oct 02 '22 19:10

rizidoro


You'd most likely be using the LIMIT and OFFSET keywords, something like this:

$sth->prepare("SELECT foo FROM bar WHERE something LIMIT ? OFFSET ?");
$sth->execute($limit, $offset);
while ( my @row = $sth->fetchrow_array ) { # loop contains 25 items

The $limit and $offset variables would be controlled by the parameters passed to your script by html/cgi/whatever features.

like image 23
TLP Avatar answered Oct 02 '22 18:10

TLP


Pagination is one of those problems a lot of CPAN modules have already solved. If you're using straight SQL, you could look at something like DBIx::Pager. You might also want to check out something like Data::Pageset to help you manage creating the links to your various pages. If you're using DBIx::Class (which is an excellent tool) for your SQL queries, then DBIx::Class::ResultSet::Data::Pageset will make this very easy for you.

Essentially handling the SQL is one end of it, but you'll also need to solve various problems in the templating aspect of it. I'd encourage you to have a look at these modules and maybe even poke around CPAN a little bit more to see where somebody else has already done the heavy lifting for you with respect to pagination.

like image 42
oalders Avatar answered Oct 02 '22 18:10

oalders