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')
它应该对我在连接到此 DataSet
的 DBGrid
中显示的数据进行排序,如下所示:
- 在
priority
列中包含 urgent
的行应该开始 DBGrid 列表。
- 然后列表应该继续
priority
列中标记为 normal
的列表,
- 后面是
state
列中标记为 wait
的那些,
- 后面是
state
列中标记为 executed
的那些,
- 最后,列表以
state
列中标记为 done
的列表结尾。
但它并没有,事实上它有点,但它实际上是倒退的。
这是我制作的一个快速视频,向您展示发生了什么,也许您可以通过这种方式获得更清晰的视图:
我猜这是因为我正在使用 ID column
或 Date column
但如果是这样,我不知道如何以及为什么。
这 2 列看起来是这样 like/are 设置的:
- ID 列设置为 Primary 和 Unique,Auto_Increment - 就是这样,没有索引或任何其他选项
如果不是那两列的问题,那么也许是 DBGrid?
我正在使用 RAD Studio 10 Seattle、dbExpress 组件(TSimpleDataSet 等)和 MySQL db
关于如何解决这个问题有什么想法吗?谢谢!
你正在为自己的生活增添不必要的困难。
没有必要让服务器进行排序(通过使用 ORDER BY 子句,并且可以说在客户端而不是在服务器上进行排序更好,因为客户端通常有空闲的计算能力,而服务器可能没有。
所以,这是我建议的处理方式:
从您的 SQL 中删除 ORDER BY 并执行一个 SELECT * [...].
用 ClientDataSet 替换您的 SimpleDataSet 并在其上定义持久 TFields。进行此更改的原因是为了能够创建两个 fkInternalCalc 类型的持久字段。
在对象检查器的 TFields 编辑器中,定义两个名为 PriorityCode 和 StateCode 的 fkInternalCalc 字段。
将数据集的 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
字段。
我在 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 列看起来是这样 like/are 设置的:
- ID 列设置为 Primary 和 Unique,Auto_Increment - 就是这样,没有索引或任何其他选项 如果不是那两列的问题,那么也许是 DBGrid?
我正在使用 RAD Studio 10 Seattle、dbExpress 组件(TSimpleDataSet 等)和 MySQL db
关于如何解决这个问题有什么想法吗?谢谢!
你正在为自己的生活增添不必要的困难。
没有必要让服务器进行排序(通过使用 ORDER BY 子句,并且可以说在客户端而不是在服务器上进行排序更好,因为客户端通常有空闲的计算能力,而服务器可能没有。
所以,这是我建议的处理方式:
从您的 SQL 中删除 ORDER BY 并执行一个 SELECT * [...].
用 ClientDataSet 替换您的 SimpleDataSet 并在其上定义持久 TFields。进行此更改的原因是为了能够创建两个 fkInternalCalc 类型的持久字段。
在对象检查器的 TFields 编辑器中,定义两个名为 PriorityCode 和 StateCode 的 fkInternalCalc 字段。
将数据集的
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
字段。