起步软件技术论坛-X3

 找回密码
 立即注册
搜索
查看: 4091|回复: 9

数据集的几种过滤条件的说明

[复制链接]
发表于 2004-4-7 15:40:27 | 显示全部楼层 |阅读模式
目前有三种过滤,Filter ,SqlFilter,UserFilter,BuildFilter

一、概念:
1、SqlFilter 是从数据库过滤(后台),除了给 Text 赋值,还需置 SqlFiltered 的属性为 True 才起作用;
2、UserFilter 是从数据库过滤(后台),它没有 UserFiltered  的属性,只需要给 Text 赋值就可以;
3、Filter  是从本地过滤(客户端),与SQLFilter一样,除了给 Text 赋值外,还需要设置 Filtered  的属性为 Ture 才起作用;
4、BuildFilter
5、当 Filter、 SqlFilter、UserFilter 同时存在时,它们之间都是逻辑与(And) 关系;
6、数据导航条中的望远镜是 UserFilter,“业务信息策略”的“默认过滤条件”也是 UserFilter 。

二、因为 SQLFilter (或者 UserFilter)是服务器端过滤,而 Filter 是客户端过滤的。服务器端是可以处理参数,客户段是不可以的。就是说当你设置了SQLFilter 属性并且 SQLFiltered =True 以后,会把 SQLFilter 和 SQL语句共同来组成 SQL 语句发给数据库服务器。因此可以支持参数。

三、SQLFilter 于UserFilter 的区别就是:前者对于最终用户来说是看不见的;后者是可见的。

四、SQLFilter 、UserFilter  是发给数据库的,后台过滤;Filter、 OnFilterRecor  是客户端的过滤

注:

1、为了减少发SQL语句,当有需要更改条件时,不管是本地还是后台都不需要在前面设置条件为False。

2、如果发到服务的过滤条件没有变化,系统不会向后台再去取数据,只要条件发生变化的时候才会向后台发SQL。

3、SQLFilter 、UserFilter 如果没有发生变化,那么系统不会向后台发SQL语句,即不会重新取一次数据
回复

使用道具 举报

发表于 2004-4-29 09:32:05 | 显示全部楼层
还有一种过滤是OnFilterRecord事件
可以用代码控制复杂的条件过滤,客户端的过滤


例如:

procedure TForm1.Table1FilterRecord(DataSet: TDataSet; var Accept: Boolean);
begin
  Accept := DataSet['DateOfPayment'] > DataSet['DateOfPurchase'] + 30;
end;
回复 支持 反对

使用道具 举报

发表于 2004-5-20 14:18:14 | 显示全部楼层
关于 BuildFilter 的使用
1、方法:
关于 BuildFilter 的方法,BuildFilter 有两种写法:(这两种方法都可以是一样的)

方法一、Business.Model.BizUtils.BuildFilter(lFilter, Context, lDatabaseURL, lSQLText, nil)

procedure TMainForm.Button1Click(Sender: TObject);
var
  lFilter:string;
  lDatabaseURL:string;
  lSQLText:string;
begin
  lDatabaseURL := 'Biz:\ZSSC\ZSLIMS.Database';
  lSQLText := 'SELECT * FROM WTDB';
  lFilter := 'WTDB.WTDH=''444''';
  if Business.Model.BizUtils.BuildFilter(lFilter, Context, lDatabaseURL, lSQLText, nil) then
  begin
    TSQLDataSet(DataSetBroker1.DataSet).UserFilter := lFilter;
  end;
end;

  BuildFilter 中的参数:
  第一个 :过滤的条件
  第二个 :启动一个上下关联的作用,就写 Context
  第三个 :数据集的数据库连接字符串
  第四个 : 数据集的 SQL 语句
  第五个 : 指的在数据集中的 SQL 语句中使用到的参数

如果想弹出那个过滤的界面,那么可以使用 TSQLDataSet(DataSetBroker1.DataSet).RunDBFilter;这句话就可以了;如果想给这个过滤某个初始值,那么你就使用上面那段代码


方法二、lSQLDataSet.BuildFilter(lFilter, lSQLDataSet.FilterFields);

var
  lFilter: string;
  lSQLDataSet: TSQLDataSet;
  //lS: TStrings;
begin
  {lS := TStringList.Create;
  try
    lS.Add('zd1');
    lS.Add('zd1');}
    lSQLDataSet := TSQLDataSet(DataSetBroker1.DataSet);
    lFilter := 'DataSetBroker1.DataSet.FieldByName(''TB_XJBLB_XJXH'').AsString:=''1''';
    lSQLDataSet.BuildFilter(lFilter, lSQLDataSet.FilterFields);   { 第一个参数,传的是一个过滤的条件,第二个参数,传的是显示那些字段,默认可以写成 nil }
  {finally
    lS.Free;
  end;}
end;

说明:BuildFilter  中只能是“数据字段”,即实际的物理字段
回复 支持 反对

使用道具 举报

发表于 2004-5-20 15:59:17 | 显示全部楼层
Filter 使用

实现:
    DataSetBroker1.DataSet.Filter := 'LSZD1 = 1';
    DataSetBroker1.DataSet.Filtered := True;

清空Filter:
    DataSetBroker1.DataSet.Filter := '';
    DataSetBroker1.DataSet.Filtered := True;


说明:

    1、 Filter 条件中只能是“数据字段”(即实际的物理字段)和“临时字段”,其他的字段都不能出现在 Filter 条件中。

    2、如果 Filter 中需要有表达式计算字段,那么需要将表达式直接写到 Filter 中。例如,定义了一个表达式计算字段的表达式为:字段1+字段2,直接写到 Filter 条件中就可以了

   3、Filter不支持32位字符串,(这是Delphi的限制,不是平台的限制),可以通过其他的方法绕开,例如使用SQLFilter、OnFilterRecord事件 等进行过滤数据、或使字符型字段的内容不大于31个字符等

   4、Filter 是本地过虑,不能使用between,可以使用大于或者大于等于等变通一下。

   5、Filter 条件中不支持参数
  
   6、Filter 中条件是区分大小写

   7、filter,支持 %+英文字母(非汉字)+%,或者 汉字或者字母+%,如果要汉字过滤,使用SQLFilter
回复 支持 反对

使用道具 举报

发表于 2004-5-20 16:10:51 | 显示全部楼层
SQLFilter 使用

代码实现:
   TSQLDataSet(DataSetBroker1.DataSet).SQLFilter := 'KCSL <100';
      TSQLDataSet(DataSetBroker1.DataSet).SQLFiltered := True;

说明: SQLFilter 条件中也是只能是“数据字段”
回复 支持 反对

使用道具 举报

发表于 2004-5-24 17:36:53 | 显示全部楼层
如果过滤条件是一个日期时间型字段:
1、在 MSSQL  数据库:
   DateTimePicker1.Time := 0;
   TSQLDataSet(DataSetBroker1.DataSet).SQLFilter := '(rq >= ''' + DateToStr(DateTimePicker1.Date)+''''
      + ') and (rq < ''' + DateToStr(DateTimePicker1.Date+1)+''''+')';
   TSQLDataSet(DataSetBroker1.DataSet).SQLFiltered := True;
   DocViewXXCellLZ_BGWD1.Doc.Close;
   DocViewXXCellLZ_BGWD1.OpenView(TDocMode.dmPreview);

2、如果是Oracle 数据库
回复 支持 反对

使用道具 举报

发表于 2004-8-26 11:03:15 | 显示全部楼层
上接四楼:用to_char 函数替换DateToStr 函数就可以了。

To_char的格式和例子:

函数              返回     描述         例子
to_char(datetime, text)  text  把datetime 转换成 string  to_char('now'::datetime, 'HH12:MI:SS')  
to_char(timestamp, text)  text  把 timestamp 转换成 string  to_char( now(), 'HH12:MI:SS')  
to_char(int, text)  text  把 int4/int8 转换成 string  to_char(125, '999')  
to_char(float, text)  text  把 float4/float8 转换成 string  to_char(125.8, '999D9')  
to_char(numeric, text)  text  把 numeric 转换成 string  to_char(-125.8, '999D99S')
回复 支持 反对

使用道具 举报

发表于 2004-9-27 09:44:43 | 显示全部楼层

关于数据集的SQLfilter过滤速度

1、如果数据集所对应的数据表的记录在万条以内,如果用到SQLFilter过滤,最好能一次从数据库把数据全部提过来,然后用客户端过滤就可以了,否则每次服务端过滤的速度会很慢。
2、如果数据量很大,通过建立索引可以大大的提高过滤速度。
3、如果一个数据集一直在用一种过滤方式,比如SQLFilter,这样的话就不用再每次都执行SQLfiltered=false;因为这样的一次操作会把数据库的所有数据都提过来,这样就影响速度了。
回复 支持 反对

使用道具 举报

 楼主| 发表于 2004-12-30 10:00:28 | 显示全部楼层

日期型字段本地过滤

var
     DateTemp : TDate;
begin
    DateTemp:= DateTimePicker1.Date;
  with DataSetBroker1.DataSet do
  begin
    if Active then active:=false;
       Filter:='scrq='''+SysUtils.DateToStr(DateTemp)+'''';
       Filtered:=True;
       Active:=true;
     end
end;
回复 支持 反对

使用道具 举报

 楼主| 发表于 2005-4-26 16:04:15 | 显示全部楼层
如果在设计期,即定义数据集时设置过滤条件,因为此时的条件时SQL语句一部分,所以如果想代码来取消或者修改条件,那么只能重新发SQL语句(取消SQL语句的Where部分,或者修改Where部分)。

重新发SQL后,需要刷新数据集,否则不起作用。
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Justep Inc.

GMT+8, 2024-5-2 22:20 , Processed in 0.044987 second(s), 15 queries .

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表