繁体   English   中英

DBGrid / DataSet 无法按照 CommandText 中设置的 sql 语句进行排序

[英]DBGrid / DataSet fails to sort as per sql statement set in CommandText

我在我正在使用的DataSet CommandText属性中使用以下内容:

SELECT *
FROM table_name
ORDER BY FIELD(priority, 'urgent', 'normal'),
         FIELD(state, 'wait', 'executed', 'done')

它应该对我在连接到此DataSetDBGrid显示的数据进行排序,如下所示:

    1. priority列中包含urgent的行应启动 DBGrid 列表。
    2. 然后列表应该继续在priority列中标记为normal的列表,
    1. 其次是state列中标记为wait的那些,
    2. 其次是state栏中标记为已executed的那些,
    3. 最后列表以state列中标记为done的列表结尾。

但它没有,实际上它有点像,但它实际上是倒退的。 这是我制作的一个快速视频,向您展示发生了什么,也许您可​​以通过这种方式获得更清晰的视图:

正在发生的事情的视频

我猜这是因为我使用的ID columnDate column但如果是这样,我不知道如何以及为什么。

这是这 2 列的外观/设置方式:

在此处输入图片说明

  • ID 列设置为 Primary 和 Unique 以及 Auto_Increment - 就是这样,没有索引或任何其他选项如果不是那两列问题,那么也许是 DBGrid?

我正在使用 RAD Studio 10 Seattle、dbExpress 组件(TSimpleDataSet 等)和 MySQL db

关于如何解决这个问题的任何想法? 谢谢!

你让自己的生活变得不必要地困难,按照你的方式去做。

没有必要让服务器进行排序(通过使用 ORDER BY 子句,可以说在客户端而不是在服务器上进行排序更好,因为客户端通常具有备用计算能力而服务器可能没有。

所以,这是我建议的处理方式:

  1. 从您的 SQL 中删除 ORDER BY,然后执行 SELECT * [...]。

  2. 用 ClientDataSet 替换 SimpleDataSet 并在其上定义持久性 TFields。 进行此更改的原因是为了能够创建两个 fkInternalCalc 类型的持久字段。

  3. 在 Object Inspector 的 TFields 编辑器中,定义两个 fkInternalCalc 字段,称为 PriorityCode 和 StateCode。

  4. 将数据集的IndexFieldNames属性设置为“PriorityCode;StateCode”。

  5. 在数据集的 OnCalcFields 事件中,计算 PriorityCode 和 StateCode 的值,它们将给出您希望数据行具有的排序顺序。

就像是:

procedure TForm1.ClientDataSet1CalcFields(DataSet: TDataSet);
var
  S : String;
  PriorityCodeField,
  StateCodeField : TField;
  iValue : Integer;
begin
  PriorityCodeField := ClientDataset1.FieldByName('PriorityCode');
  StateCodeField := ClientDataset1.FieldByName('StateCode');
  S := ClientDataset1.FieldByName('Priority').AsString;
  if S = 'urgent' then
    iValue := 1
  else
    if S = 'normal' then
      iValue := 2
    else
      iValue := 999;
  PriorityCodeField.AsInteger := iValue;

  S := ClientDataset1.FieldByName('State').AsString;
  if S = 'wait' then
    iValue := 1
  else
    if S = 'executed' then
      iValue := 2
    else
      if S = 'done' then
        iValue := 3
      else
        iValue := 999;
  StateCodeField.AsInteger := iValue;

end;

实际上,如果避免使用FieldByName而只使用 OI 的 Tfields 编辑器创建的字段的字段会更好(更快,更少的开销),因为这些字段在打开时会自动绑定到 ClientDataSet 的数据字段。

顺便说一句,记住虽然 TClientDataSet 不能在 TFields 编辑器中定义为Calculated的字段上排序,但它可以InternalCalc字段上排序。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM