【问题标题】:SQL table change sequenceSQL表更改顺序
【发布时间】:2013-03-30 14:14:50
【问题描述】:

我在 DBGrid 中显示了一个表格,排序顺序基于一个序列字段,我希望能够一次将一个项目向上或向下移动一个位置。我在这里进行了研究,找不到完全符合我需要的东西。

当我禁用排序顺序以进行更改时,问题出现了,列表恢复到最初输入数据的顺序,所以我丢失了下一行。

这就是我所拥有的……

Folder  Sequence
----------------
Buttons   1
Thread    2  << Current Row
Cotton    3
Rags      4

点击我想要的“MoveDown”按钮...

Folder  Sequence
----------------
Buttons   1
Cotton    2
Thread    3  << Current Row
Rags      4

但是 - 当我删除 Sequence 上的排序顺序时,我得到了输入项目的顺序...

Folder  Sequence
----------------
Buttons   1
Cotton    2
Rags      4
Thread    3  << Current Row

到目前为止,我的尝试被证明非常繁琐,包括将 Rows 加载到列表框中,将它们洗牌,然后将它们写回 Table。必须是更好的方法,但这超出了我目前对 SQL 的掌握范围。

有人可以指点我去的方向吗?

如果在 SQL 中很难做到,我不想给任何人带来太多麻烦,因为我总是可以使用列表框方法。如果对 SQL 专家来说相对简单,那么我很乐意看到 SQL 文本。

谢谢

【问题讨论】:

    标签: sql delphi


    【解决方案1】:

    我的解决方案基于按Sequence 字段排序的 TDataSet:

    MyDataSet.Sort := 'Sequence';
    

    然后在当前行Next(向下)/Prior(向上)记录之间交换Sequence字段,例如:

    type
      TDBMoveRecord = (dbMoveUp, dbMoveDown);
    
    function MoveRecordUpDown(DataSet: TDataSet; const OrderField: string;
      const MoveKind: TDBMoveRecord): Boolean;
    var
      I, J: Integer;
      BmStr: TBookmarkStr;
    begin
      Result := False;
      with DataSet do
      try        
        DisableControls;
        J := -1;
        I := FieldByName(OrderField).AsInteger;
        BmStr := DataSet.Bookmark;
        try
          case MoveKind of
            dbMoveUp: Prior;
            dbMoveDown: Next;
          end;
          if ((MoveKind = dbMoveUp) and BOF) or ((MoveKind = dbMoveDown) and EOF) then
          begin
            Beep;
            SysUtils.Abort;
          end
          else
          begin
            J := DataSet.FieldByName(OrderField).AsInteger;
            Edit;
            FieldByName(OrderField).AsInteger := I;
            Post;
          end;
        finally
          Bookmark := BmStr;
          if (J <> -1) then
          begin
            Edit;
            FieldByName(OrderField).AsInteger := J;
            Post;
            Result := True;
          end;
        end;
      finally
        EnableControls;
      end;
    end;
    

    用法:

    MoveRecordUpDown(MyDataSet, 'Sequence', dbMoveDown);    
    // or     
    MoveRecordUpDown(MyDataSet, 'Sequence', dbMoveUp);
    

    【讨论】:

    • 如果Sequence 设置为表的PRIMARY KEY,这不会违反该约束并引发异常吗??
    • @LightBulb,PK 根本不应该改变。但是将索引设置为Sequence 就可以了。
    • @kobik 感谢您提供如此多的细节,我非常感谢。这个过程比我想象的要复杂得多,现在我明白我为什么要为此苦苦挣扎了。
    • LB:这个字段,“Sequence”,正如 Kobik 推测的那样,是一个普通字段,而不是主键字段,所以没有风险,但还是感谢您的谨慎。
    【解决方案2】:

    如果我理解正确,你想找到“下一个序列项”吗? 也许你可能会做一些类似“获得第一个最小值,然后是 X”的事情? 这样就可以通过prev了。行序列值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-07
      • 1970-01-01
      • 2011-07-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-03-12
      相关资源
      最近更新 更多