数据太大,怎么分页显示?

ncoxwwz 2005-07-21 11:43:27
各位大侠:
我用的数据库是SQL ,用存储过程查询想要的数据,用DATAGRID显示查询的数据,但因为数据太大了,所以要等很久才能显示出来,我想问各位大侠,怎么样做到每次查询只查询一定数据量的数据,然后显示在DATAGRID中,比如每次只查询显示30笔数据,等到下拉滚动条时,再把后30笔数据显示出来,或者还有什么更好的办法,请各位赐教!谢谢!
...全文
777 19 打赏 收藏 转发到动态 举报
写回复
用AI写文章
19 条回复
切换为时间正序
请发表友善的回复…
发表回复
zgengle 2006-02-20
  • 打赏
  • 举报
回复
mark
yeweimian1 2005-09-17
  • 打赏
  • 举报
回复
最后楼主你分页采用哪种方法啊???效率如何!!!
ncoxwwz 2005-08-22
  • 打赏
  • 举报
回复
谢谢各位,已解决!
ncoxwwz 2005-07-27
  • 打赏
  • 举报
回复
太感谢各位了。
xuancaoer 2005-07-22
  • 打赏
  • 举报
回复
mark
Erice 2005-07-21
  • 打赏
  • 举报
回复
用TClientDataSet结合TQuery来完成,但是要求你的数据表中要有一个唯一索引字段,最好是自增字段

代码如下
Function GetNextData(CdsGridview:TClientDataSet;EdtView:TEdit;sTable,sField,sWhere,sTop:String;Var LocalCount:Integer):Boolean; //获取下一包数据
Var
Odata:OleVariant;
sSql:String;
begin
Result:=False;
screen.Cursor := crhourglass;
With CdsGridview do
Begin
if Not Active then Exit;

sSql:='Select Top '+sTop+sField
+' From '+sTable+' Where 1=1 '+sWhere;
Odata:=null;
InterSales.qurrecords(sSql,Odata);
DisableControls;
if Not VarisNull(Odata) then
begin
if Active then Close;
Open;
AppendData(Odata,true);
Odata:=null;
//得到此次查询的键值
LocalCount := GetKeyFieldValue('ID',CdsGridView);
EnableControls;
EdtView.Clear;
EdtView.Text:='当前下载记录:'+IntToStr(CdsGridView.RecordCount)+'条';
Result:=True;
end else
begin
EnableControls;
screen.Cursor := crdefault;
exit;
end;
screen.Cursor := crdefault;
End;
end;
chenchangfu 2005-07-21
  • 打赏
  • 举报
回复
SET ROWCOUNT 30
GO
select * from table1
每次需要数据都去查一次select * from table1就可以
chenchangfu 2005-07-21
  • 打赏
  • 举报
回复
SET ROWCOUNT 4
GO
select * from table1
lsh_ahjz 2005-07-21
  • 打赏
  • 举报
回复
看在存储过程的记录移动事件里执行 使用TOP 看看可以达到你的要求不
cumtbwxj 2005-07-21
  • 打赏
  • 举报
回复
不错想法。


学习
Erice 2005-07-21
  • 打赏
  • 举报
回复
GetKeyFieldValue的函数原形:
function GetKeyFieldValue(sortField:string;clientdb:TClientDataSet): OleVariant;
var
aCDS : TClientDataSet;
begin
aCDS:=TClientDataSet.Create(nil);
try
try
if not varisnull(clientdb.Data) then
begin
///如果重新按其他列排序后,此处可能不对了 !
aCDS.Data:=clientdb.Data;
WITH acds do begin
IndexName := '';
IndexDefs.Update;
end;
with aCDs.IndexDefs.AddIndexDef do
begin
Fields := sortField;
Options := [];
end;
aCDs.IndexDefs.Update;
aCDS.Last;
Result:=aCDS.FieldByName(sortfield).Value;
end;
finally
aCDS.Free ;
end;
except
on e: Exception do
raise;
end;
end;
Erice 2005-07-21
  • 打赏
  • 举报
回复
我上面的例子用于分布式程序的(有几个小函数需要自己写:
1。InterSales.qurrecords----一个接口函数用于根据SQL获取记录,需要自己修改
2。GetKeyFieldValue---获得当前查询记录的最大的自增ID;),
还可以用于C/S。速度还可以,1000条记录在本机上可以和C/S的程序相比,在INTERBET上比C/S的快。用于C/S时,对源程序不用做大幅度的修改,只要修改DBGRID的DATASOURCE的属性指向,具体可以互相交流
djfu 2005-07-21
  • 打赏
  • 举报
回复
楼主看看这个,一定会很有启发的:
http://access911.net/fixhtm/72FAB41E14DC.htm


【问题】:
如何用sql返回第三条或者第三条记录开始返回?
从数据库中的表中从第三条记录开始取,那么select该怎么写呢?

【回答】:
select * from table_name where id_field not in (select top 3 id_field from table_name)
注意,其实就是把 select top 语句写两遍,第二遍包含了第一遍,然后把是第一遍中的记录用not in剔除就可以了,所以两个where都必须包含相同的外加条件。

asp 中经常用来写 pageno 的程序,因为直接用ado的pagesize如果遇上几十万数据,用pagesize就完蛋喽。
关于 not in 语句速度比较慢,某人提示将not in改为
select table2.* from table2 left join table1 on table2.key=table1.key where (able1.key is null)

返回第3条记录用:
select top 1 * from (SELECT top 3 a.编号 FROM a order by 编号) as b order by 编号 desc

如果用来进行分页,返回第100-150条记录,可以用
select top 50 * from (SELECT top 150 a.编号 FROM a order by 编号) as b order by 编号 desc

paranoia190 2005-07-21
  • 打赏
  • 举报
回复
硬件最实际!
liuqifeiyu 2005-07-21
  • 打赏
  • 举报
回复
hhzqf1980(hh)
好象是只是实现了分页显示,却没有对速度有什么大的提高。
不知道我的理解对吗?
hhzqf1980 2005-07-21
  • 打赏
  • 举报
回复
unit Unit1;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, DB, ADODB, Grids, DBGrids, StdCtrls,adoint;

type
TForm1 = class(TForm)
DBGrid1: TDBGrid;
aqStore: TADOQuery;
Button1: TButton;
Button2: TButton;
Button3: TButton;
Button4: TButton;
Button5: TButton;
dsstore: TDataSource;
lblCount: TLabel;
procedure FormShow(Sender: TObject);
procedure Button1Click(Sender: TObject);
procedure ShowData(iPage: Integer);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure Button5Click(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;

var
Form1: TForm1;

implementation
var
pCount: Integer;
curPage: Integer = 1;
adsClone: TADODataSet;
{$R *.dfm}

procedure TForm1.FormShow(Sender: TObject);
begin
with aqStore do
begin
Close;
SQL.Clear;
SQL.Add('select * from users');
Open;
end;
adsClone := TADODataSet.Create(self);
aqStore.Recordset.PageSize := 5;
pCount := aqStore.Recordset.PageCount;
ShowData(1);
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Form1.Close;
end;

procedure TForm1.ShowData(iPage: Integer);
procedure CreadeAdsField;
var
i: Integer;
begin
adsClone.Close;
adsClone.FieldDefs.Clear;
for i := 0 to aqStore.FieldCount - 1 do
begin
adsClone.FieldDefs.Add(aqStore.Fields[i].FieldName, aqStore.Fields[i].DataType, aqStore.Fields[i].Size);
end;
adsClone.CreateDataSet;
end;
var
i, j: Integer;
rs: adoint.RecordSet;
begin
aqStore.Recordset.AbsolutePage := iPage;
rs := aqStore.Recordset;
CreadeAdsField;
adsClone.DisableControls;

for i := 0 to rs.PageSize - 1 do
begin
adsClone.append;
for j :=0 to rs.Fields.Count - 1 do
adsClone.Fields[j].Value := rs.Fields[j].Value;
rs.MoveNext;
if rs.EOF then Break;
end;
adsClone.EnableControls;
adsClone.First;
dsStore.DataSet := adsClone;
lblCount.Caption := '页次:' + IntToStr(iPage) + '/' + IntToStr(pCount);
end;
procedure TForm1.Button2Click(Sender: TObject);
begin
curPage := 1;
ShowData(curPage);
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
if curPage = 1 then
begin
MessageBox(self.Handle, '已到了首页!', '提示', mb_IconInformation + mb_Ok);
Exit;
end;
Dec(curPage);
ShowData(curPage);
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
if curPage = pCount then
begin
MessageBox(self.Handle, '已到了末页!', '提示', mb_IconInformation + mb_Ok);
Exit;
end;
Inc(curPage);
ShowData(curPage);
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
curPage := pCount;
ShowData(curPage);
end;

end.
ncoxwwz 2005-07-21
  • 打赏
  • 举报
回复
各位,能不能举例详细说明啊,谢谢!
WuChenCan 2005-07-21
  • 打赏
  • 举报
回复
用TOP N 呀,如果是三层可以看李维写的那本分布式应用系统开发书,里面有讲到分包取数
djfu 2005-07-21
  • 打赏
  • 举报
回复
楼主的想法是可以理解的。

因为如果服务器上的一个数据表有100万条记录,
那么如果你用 select * from ServerTable;

那么返回一百万条记录,你自己的机子都会崩溃,
等待时间恐怕也要一天一夜了。。。

所以,我们可以用前 N 条记录查询的方法,
一次取1000条或500条。

2,497

社区成员

发帖
与我相关
我的任务
社区描述
Delphi 数据库相关
社区管理员
  • 数据库相关社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧