[英]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')
它应该对我在连接到此DataSet
的DBGrid
显示的数据进行排序,如下所示:
priority
列中包含urgent
的行应启动 DBGrid 列表。priority
列中标记为normal
的列表,state
列中标记为wait
的那些,state
栏中标记为已executed
的那些,state
列中标记为done
的列表结尾。但它没有,实际上它有点像,但它实际上是倒退的。 这是我制作的一个快速视频,向您展示发生了什么,也许您可以通过这种方式获得更清晰的视图:
我猜这是因为我使用的ID column
或Date column
但如果是这样,我不知道如何以及为什么。
这是这 2 列的外观/设置方式:
我正在使用 RAD Studio 10 Seattle、dbExpress 组件(TSimpleDataSet 等)和 MySQL db
关于如何解决这个问题的任何想法? 谢谢!
你让自己的生活变得不必要地困难,按照你的方式去做。
没有必要让服务器进行排序(通过使用 ORDER BY 子句,可以说在客户端而不是在服务器上进行排序更好,因为客户端通常具有备用计算能力而服务器可能没有。
所以,这是我建议的处理方式:
从您的 SQL 中删除 ORDER BY,然后执行 SELECT * [...]。
用 ClientDataSet 替换 SimpleDataSet 并在其上定义持久性 TFields。 进行此更改的原因是为了能够创建两个 fkInternalCalc 类型的持久字段。
在 Object Inspector 的 TFields 编辑器中,定义两个 fkInternalCalc 字段,称为 PriorityCode 和 StateCode。
将数据集的IndexFieldNames
属性设置为“PriorityCode;StateCode”。
在数据集的 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.