как разбить на страницы ResultSet

User avatar
webdeveloper
Уже с Приветом
Posts: 2049
Joined: 12 Jul 2000 09:01
Location: Madison, Wisconsin USA

как разбить на страницы ResultSet

Post by webdeveloper »

Так, что, в итоге нет способа разбить ResulSet на старницы в базе данных когда используется хранимаю процедура?

Или есть?

Варианты с созданием дополнительных таблиц не предлогать [img:2c4d18eca0]images/smiles/icon_smile.gif[/img:2c4d18eca0]
AK70
Уже с Приветом
Posts: 3127
Joined: 10 Apr 2001 09:01
Location: MD

как разбить на страницы ResultSet

Post by AK70 »

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">quote:</font><hr>Originally posted by Jim:
<strong>
запоминая ID этих записей
</strong><hr></blockquote>

do you mean ROWID of Oracle?
I bet you won't get the grand prix for performance with your solution [img:9e563c8c62]images/smiles/icon_smile.gif[/img:9e563c8c62]

if you use deletion on the temp table, it means that your solution is naturally ineffective, because first you created those rows, then deleted 'em, both operations are not the quickest ones.

the solution with views is elegant, and not the slowest one. I advised it to some of my clients, they are happy. it's Oracle, of course. in SQL server it's not that nice.

something like this:
CREATE VIEW V AS
SELECT C,
(SELECT COUNT(*) FROM T t1 WHERE t1.C <= T.C) row
FROM T

this works when you have a primary key on C, like
create table T(
C VARCHAR2(2) primary key
)

-------------
obviously, this looks uglier than in Oracle, because MS SQL sucks [img:9e563c8c62]images/smiles/icon_smile.gif[/img:9e563c8c62] just kidding

If there's no primary key, then you are going to create a temp table like
CREATE TABLE TT (
C VARCHAR2(2),
row int IDENTITY (1, 1)
)

I don't like temp tables. They may be more effective than views, usually, but for aestethical reasons I hate them.
VYLE
Уже с Приветом
Posts: 1772
Joined: 06 Sep 2001 09:01
Location: Boston, MA -> Charlotte,NC ->Danbury,CT

как разбить на страницы ResultSet

Post by VYLE »

Если есть primary key - с, то разве нельзя делать просто запрос типа
select top 10 from t where t.c >= c_ses order by c

где с_ses - это текущее значение ключа, которое хранится в сессионной переменной, и обновляется после каждого запроса ?

Или я неправ ?
AK70
Уже с Приветом
Posts: 3127
Joined: 10 Apr 2001 09:01
Location: MD

как разбить на страницы ResultSet

Post by AK70 »

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">quote:</font><hr>Originally posted by VYLE:
<strong>Если есть primary key - с, то разве нельзя делать просто запрос типа
select top 10 from t where t.c >= c_ses order by c

где с_ses - это текущее значение ключа, которое хранится в сессионной переменной, и обновляется после каждого запроса ?

Или я неправ ?</strong><hr></blockquote>

if it was just top 10, there wouldn't be a discussion here [img:cde53abb6b]images/smiles/icon_smile.gif[/img:cde53abb6b]
say you want rows between 100th and 125th. there's no standard SQL construct for that. so, we do all vendor specific tricks
User avatar
webdeveloper
Уже с Приветом
Posts: 2049
Joined: 12 Jul 2000 09:01
Location: Madison, Wisconsin USA

как разбить на страницы ResultSet

Post by webdeveloper »

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">quote:</font><hr>Originally posted by tengiz:
<strong>webdeveloper, а Вы вроде до сих пор не сказали, о каком сервере БД идёт речь. Или я что-то пропустил?</strong><hr></blockquote>

В данный момент я на SQL Server, но это пока просто тренировчный проектик. Сижу изучаю JSP. Вот и заинтересовался как это можно сделать. А в книжке ответов на этот вопрос не нашел. Вот и решил спросить.

Оракл я вообще не знаю и даже ни разу не видел [img:670d15dc2d]images/smiles/icon_smile.gif[/img:670d15dc2d] Поэтому про него я пока не думаю, и даже не могу про него вопрос задать. Но хотелось бы конечно знать какой нибудь универсальный способ для реализации этой задачи. Если он конечно существует.
Frank
Уже с Приветом
Posts: 2019
Joined: 22 Jul 2000 09:01

как разбить на страницы ResultSet

Post by Frank »

Вот так как!!!

Хе-хе, потому-то MySQL так и популярен для создания web-страниц, что там есть несколько удобных команд, включая и LIMIT.
SELECT * FROM mytable WHERE ... ORDER BY ... LIMIT 1500, 10;

Ну, и скорость, канешна. Она позволяет строить довольно интересные приложения со сложными алгоритмами.
Andrey2
Уже с Приветом
Posts: 157
Joined: 13 Dec 1999 10:01
Location: Eburg/Russia -> Walnut Creek,CA,USA

как разбить на страницы ResultSet

Post by Andrey2 »

IMHO

1. Use ResultSet scrolling. ResultSet.absolutePage() is a shortcut (same idea, but would be completed by db server/driver, IMHO).

2. Limit the number of recordset, returned from stored procedure (something like select top 500 in sp; may be a property to java.sql.Statement). You will be hardly ever asked to show 20-th page of results, more likely you will be asked to sort results.

3. You may try to incapsulate both ideas inside your stored procedure.

Forget about session-dependent storing -- it consumes a lot of resources (runtime and delopment time). Sequental requests to database would probably use caching on db side.

MySQL LIMIT clause works (at least worked couple of years ago, AFAIK) the same way (limits with a number of resulting records and then scans through results) but on driver level.

Sorry for english,
Andy
User avatar
WildVlad
Уже с Приветом
Posts: 3982
Joined: 13 Jul 2000 09:01
Location: SVX -> BOS -> BUR -> SJC

как разбить на страницы ResultSet

Post by WildVlad »

Не типа, есть вот такой глупый вариант (я его уже как-то описывал).
Для начала нужно определиться будут ли пользователи чаще всего просматривать все страницы или ограничится, скорее всего первыми n из них.
Выбрав стратегию действуем так:
1. Просмотр всех страниц вероятен. Стартуем новую нить (делается через Bean, который на самом деле практически обычный java-класс в JSP), которая и сгенерит в temporary storage нужные страницы. Основная нить (обаботчик запросов броузера) же спрашивает у этной нити: А не готова ли страница номер k? И ждёт если не готова.
2. Наиболее вероятно, что пользователя задолбает смотреть результаты уже где-то на 5-6-...-10 й странице. Ну и генерим сразу кусками по 10 страниц. Если попросил, к примеру, 8-9, то мы смотрим: ага! Тык эта сволочь скоро и до 10-ой доберётся, так значит нам надо подготовить страницы 11-20, а страницы 1-6 можно и потереть (а можно и нет). При этом пропуск страниц можно тупо реализовать пропуская первые RowsPerPage*10 записей. Всё равно, из хранимой процедуры даже если и удастся создать Scrollable cursor, придётся их считывать, не вы сами, так драйвер за это вас сделает.

Тут даже вопрос то не в том, а вот в чём:
Раз у вас есть хранимая процедура, то может вы ей и сделатет параметром какие страницы она должна выплюнуть?
koreiko
Новичок
Posts: 39
Joined: 18 Nov 2001 10:01
Location: not for a while yet in Moscow

как разбить на страницы ResultSet

Post by koreiko »

Если JDBC 1.0, то похоже действительно нужно каждый раз бегать по всему ResultSet

А в версии 2.0 все намного проще:

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">code:</font><hr><pre>
// Recordset rs ;

int numberOfRecords = 0;
try {
if (rs.last()) {
numberOfRecords = rs.getRow();
rs.beforeFirst(); // возвращаем курсор на место, хотя можно сделать это и потом
}
} catch (SQLException e) {
System.out.println("Фак твою мать "+e.toString())
}
</pre><hr></blockquote>

Теперь имеем количество записей в ResultSet и можно выводить по тому же принципу, как и в ASP, типа как написал stockman
Для переходов по страницам используем код

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">code:</font><hr><pre>
void moveToPage (int pageNumber) {

try {
rs.absolute(10*(pageNumber-1)+1)
} catch (SQLException e) {}

}
</pre><hr></blockquote>

Приблизительно так, если я правильно понял, в чем проблема.

[ 20-11-2001: Message edited by: koreiko ]</p>
koreiko
Новичок
Posts: 39
Joined: 18 Nov 2001 10:01
Location: not for a while yet in Moscow

как разбить на страницы ResultSet

Post by koreiko »

2 keyik:

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">quote:</font><hr>P.S. Пока писал ответ, увидел, что нечто подобное уже ответил koreiko [img:16b7f55136]images/smiles/icon_smile.gif[/img:16b7f55136]
<hr></blockquote>

Долго же ты ответ писал [img:16b7f55136]images/smiles/icon_biggrin.gif[/img:16b7f55136]
keyik
Новичок
Posts: 22
Joined: 14 Jun 2000 09:01
Location: Атланта

как разбить на страницы ResultSet

Post by keyik »

<blockquote><font size="1" face="Arial, Verdana, Helvetica, sans-serif">code:</font><hr><pre>
for( int i=0; i<=startRec+pageSize && rs.next(); i++ )
{
if ( i>startRec && i<=startRec+pageSize )
doSomething();
}
</pre><hr></blockquote>[/qb]<hr></blockquote>

Webdeveloper, а чем не устраивает предложенный выше вариант? Только надо "next()" заменить на "absolute(int row)" и перед циклом надо будет подрегулировать "startRec" парой "if"-ов.

Чтобы работал "absolute(int row)", надо создать "Statement" c соотв.параметрами, что типа такого:

Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE).

Я уже точно не помню параметры [img:6db8f0cd40]images/smiles/icon_smile.gif[/img:6db8f0cd40] Идея в том, чтобы по курсору можно было "ездить" как хочешь, в любую сторону. В Оракле, в каталоге [ORACLE_HOME]/ora8i/jdbc/ есть примерчики на этот счет в виде zip-файла, по-моему, файл называется "ResultSet5.java" [img:6db8f0cd40]images/smiles/icon_smile.gif[/img:6db8f0cd40]

Дальше надо прилепить кнопки "Next", "Prev" и т.д. и по ним вызывать этe же jsp-страницу с параметром, что типа такого:

<%@ import "myproject.db.*" %>
<%
...
MyView mv = new MyView(); // это из "myproject.db.*"
int startRec = ....request.getParameter("start_row");
// проверку на null и прочие преобразования я опустил
...
%>
...
<a href="tview?start_row=<%= startRec + pageSize %>">Next</a>
<a href="tview?start_row=<%= startRec - pageSize %>">Prev</a>
...
<%
for(int i=0; i<=startRec + pageSize && mv.absolute(i); i++){ %>
<tr>
<td><%= mv.getColumn(1)%></td>
<td><%= mv.getColumn(2)%></td>
<td><%= mv.getColumn(3)%></td>
</tr>
<% } %>

Ну, надо еще добавить обработку ошибок и переадресовку на errorpage [img:6db8f0cd40]images/smiles/icon_smile.gif[/img:6db8f0cd40]

P.S. Пока писал ответ, увидел, что нечто подобное уже ответил koreiko [img:6db8f0cd40]images/smiles/icon_smile.gif[/img:6db8f0cd40]

[ 22-11-2001: Message edited by: keyik ]</p>

Return to “Вопросы и новости IT”