TClientDataSet[8]: 关于索引与排序

索引的目的有三: 快速定位、排序、建立主从表. 下面是相关属性与方法:
--------------------------------------------------------------------------------
 IndexDefs;       {  }
IndexFieldCount; {  }
IndexFieldNames; {  }
IndexFields[];   {  }
IndexName;       {  }

AddIndex();      {  }
DeleteIndex();   {  }
GetIndexInfo();  {  }
GetIndexNames(); {  }
--------------------------------------------------------------------------------

添加索引的方法有二:
 1、用 IndexFieldNames 通过字段名(多个字段用 ; 隔开)指定临时索引;
 2、通过 IndexDefs.AddIndexDef 或 AddIndex 建立索引, 然后用 IndexName 指定为当前索引.

两种方法都可以在设计时完成; 后者会有更多功能, 譬如倒排序; 两种方法是互斥的, 指定一个会自动取消另一个.

TClientDataSet 会自动生成两个默认索引: DEFAULT_ORDER、CHANGEINDEX; 它们都不允许用户删改.
 CHANGEINDEX 是用于 Delta(日志)的.

DEFAULT_ORDER 可用于恢复默认排序; 它可能已经和某些字段关联, 如(xml 源码):
 <PARAMS DEFAULT_ORDER="1" PRIMARY_KEY="1" ... /> 或
 <PARAMS DEFAULT_ORDER="1 2" PRIMARY_KEY="1 2" ... />
--------------------------------------------------------------------------------

关于临时索引最常用的代码是在 DBGrid 的 OnTitleClick 事件中更换索引, 如:
--------------------------------------------------------------------------------

 { 根据当前字段排序 }
procedure TForm1.DBGrid1TitleClick(Column: TColumn);
begin
  if not Column.Field.IsBlob then { 不能给大二进制字段建立索引或排序 }
    ClientDataSet1.IndexFieldNames := Column.FieldName;
end;

{ 恢复默认排序 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  ClientDataSet1.IndexName := 'DEFAULT_ORDER';
end;
--------------------------------------------------------------------------------

使用 IndexFieldNames 可指定多个字段, 如: ClientDataSet1.IndexFieldNames := '字段x; 字段y; 字段z';
 此时顺序很重要, 这里会先按 "字段x" 排序; 在 "字段x" 的值相同时会按 "字段y" 排序; 在 "字段y" 的相同时...

IndexFieldNames 没有更多了, 更复杂的排序就需要建立排序对象(TIndexDef)了.
--------------------------------------------------------------------------------

实现倒排序的例子:
--------------------------------------------------------------------------------
 { 下面是在 holdings.xml 的基础上建立的两个索引; ACCT_NBR、SYMBOL 是其中的两个字段 }
procedure TForm1.FormCreate(Sender: TObject);
begin
  ClientDataSet1.AddIndex('Index_1', 'ACCT_NBR; SYMBOL', []);             { 正序 }
  ClientDataSet1.AddIndex('Index_2', 'ACCT_NBR; SYMBOL', [ixDescending]); { 倒序 }
  ClientDataSet1.IndexName := 'Index_1';
end;

{ 切换上面建立的两个索引 }
procedure TForm1.Button1Click(Sender: TObject);
begin
  if ClientDataSet1.IndexName = 'Index_1' then
    ClientDataSet1.IndexName := 'Index_2'
  else
    ClientDataSet1.IndexName := 'Index_1';
  ClientDataSet1.First;
end;
--------------------------------------------------------------------------------

{ 上面的 TForm1.FormCreate 过程也可以写作(另一种建立方法) }
procedure TForm1.FormCreate(Sender: TObject);
begin
  with ClientDataSet1.IndexDefs.AddIndexDef do
  begin
    Name := 'Index_1';
    Fields := 'ACCT_NBR; SYMBOL';
  end;
  with ClientDataSet1.IndexDefs.AddIndexDef do
  begin
    Name := 'Index_2';
    Fields := 'ACCT_NBR; SYMBOL';
    Options := [ixDescending];
  end;
  ClientDataSet1.IndexName := 'Index_1';
end;
--------------------------------------------------------------------------------

 关于 AddIndex:
--------------------------------------------------------------------------------
 AddIndex(
  const Name: string;          { 索引名称; 不能重名 }
  const Fields: string;        { 索引字段; 多个字段用分号隔开; 默认升序排列 }
  Options: TIndexOptions;      { 选项 }
  const DescFields,            { 按降序排列的字段; 须先在 Fields 中列出 }
  const CaseInsFields: string; { 不区分大小写的字段; 须先在 Fields 中列出 }
  const GroupingLevel: Integer { 分组级别, 用于分组统计的 }
);

//Options:
IxPrimary         { 主索引 }
IxUnique          { 字段值无重复 }
ixDescending      { 降序 }
ixCaseInsensitive { 不区分大小写 }
ixExpression      { 无用 }
ixNonMaintained   { 无用 }
{ 可选空值 [], 最多不能多于两个选项 }
{ 若是两个选项, 其中之一须是: ixDescending 或 ixCaseInsensitive }
--------------------------------------------------------------------------------

AddIndex 的一些用法(都是先 F1 后 F2):
--------------------------------------------------------------------------------
 //F1、F2 降序, 两种写法一样:
AddIndex('Index_1', 'F1; F2', [ixDescending]);
AddIndex('Index_2', 'F1; F2', [], 'F1; F2');

//F1、F2 不区分大小写排序(不指定降序则默认升序):
AddIndex('Index_1', 'F1; F2', [ixCaseInsensitive]);
AddIndex('Index_2', 'F1; F2', [], '', 'F1; F2');

//F1 升序, F2 降序:
AddIndex('Index_1', 'F1; F2', [], 'F2');
AddIndex('Index_2', 'F1; F2', [ixDescending], 'F2'); { 此时 [ixDescending] 被忽略 }

//F1 降序, F2 升序:
AddIndex('Index_1', 'F1; F2', [], 'F1');
AddIndex('Index_2', 'F1; F2', [ixDescending], 'F1');
--------------------------------------------------------------------------------

AddIndex 能做到的, 用 IndexDefs.AddIndexDef 也可以, 并且也都能在设计时完成.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值