ADOQuery, операторы SQL и переупорядочение строк в базе данных - PullRequest
0 голосов
/ 03 февраля 2011

У меня есть таблица базы данных с именем P_Columns.Эта таблица содержит столбцы

ID
Column_Name
Column_Type
Column_Visible
Column_Order

Эта таблица данных заполняется и обновляется приложением, которое отображает сетку dbgrid.Это приложение имеет кнопку.что при нажатии он занимает выбранную строку.и поднимает его на один ряд (это где мне нужна помощь).

Теперь мой первоначальный оператор SQL (SELECT * FROM P_Columns Order by Column_Order asc) устанавливает правильный порядок.первоначально.

Мне нужно выяснить, есть ли оператор обновления Sql, который позволит мне поменять Column_Order выбранной записи.с записью непосредственно перед ней.

Надеюсь, это имеет смысл.

Ответы [ 4 ]

0 голосов
/ 03 февраля 2011

Я могу ошибаться, но, похоже, в этом случае вам не нужно иметь только одно утверждение.Я также не вижу, что это подразумевается, поскольку вы говорили только о выражении UPDATE , что не означает, что у вас не может быть никаких других утверждений, готовящих обновление, не так ли?Но если ты это имел в виду, прости меня, пожалуйста, но я собираюсь идти дальше.:)

Во-первых, я хотел бы знать, действительно ли в вашем Column_Order нет пробелов.Потому что, если нет пробелов и , значения начинаются с 1, тогда решение cyberkiwi можно обойтись только с этой модификацией (однако все кредиты должны идти этому человеку):

declare @order int;
set @order = :order;

update P_Columns
set Column_Order =
  case 
    when Column_Order = @order then Column_Order - 1 
    else Column_Order + 1 
  end
where Column_Order in (@order, @order - 1) and @order > 1

То есть вам нужно объявить @var, чтобы вы использовали :order только один раз для скрипта.(Возможно, вы уже знали об этом.) И вот, пожалуйста.

Однако, если это решение не может быть применено как есть, тогда, в принципе, я думаю, вам просто нужно добавить больше операторов, чтобы вычислить заранее другоестоимость заказа должна быть обменена, затем обновите.

Вот как это может быть:

declare @order int, @prev_order int;
set @order = :order;

/* here goes looking up for the other Column_Order */
select @prev_order = max(Column_Order)
from P_Columns
where Column_Order < @order;

/* and now update, which is basically the same,
   only adapted for use with @prevorder,
   and also we check if @prevorder has a value */
if @prevorder is not null
  update P_Columns
  set Column_Order =
    case Column_Order
      when @order then @prevorder
      else @order
    end
  where Column_Order in (@order, @prevorder)

Если у вас есть какие-либо вопросы, они приветствуются.

0 голосов
/ 03 февраля 2011

Поменяйте местами только две позиции.Последний AND :order > 1 используется для того, чтобы позиция 1 не могла поменяться местами с позицией 0 (не существует)

update datatable
set column_order = case 
                      when column_order = :order then column_order-1 
                      else column_order+1 
                   end
where column_order in (:order, :order-1)
  and :order > 1

Оператор CASE должен существовать в большинстве основных СУБД.

Примечание: в TADOQuery (складе) есть ошибка, из-за которой все 4 :order параметра не будут установлены сразу.Требуются 4 параметра, все из которых имеют одинаковое значение, если не известно, что СУБД оптимизирует запрос для конкретной СУБД.

0 голосов
/ 03 февраля 2011

Вот код Delphi, который делает то, что вы хотите, используя TADOCommand, дважды вызывая оператор обновления.Это проверено на MS SQL Server.Если вы не используете компоненты TADO *, вы сможете преобразовать их в любые используемые вами компоненты базы данных.ADODataSet1 - это данные, представленные в сетке.

var
    CurrentID: Integer;
    CurrentOrder: Integer;
    PrevID: Integer;
    PrevOrder: Integer;
begin
    if ADODataSet1.RecNo > 1 then // Do not move the first row
    begin
        CurrentID := ADODataSet1['ID'];
        CurrentOrder := ADODataSet1['Column_Order'];

        ADODataSet1.Prior;
        PrevID := ADODataSet1['ID'];
        PrevOrder := ADODataSet1['Column_Order'];

        ADOCommand1.CommandText := 'update P_Columns set Column_Order = :Column_Order where ID = :ID';

        ADOCommand1.Parameters.ParamByName('Column_Order').Value := PrevOrder;
        ADOCommand1.Parameters.ParamByName('ID').Value := CurrentID;
        ADOCommand1.Execute;

        ADOCommand1.Parameters.ParamByName('Column_Order').Value := CurrentOrder;
        ADOCommand1.Parameters.ParamByName('ID').Value := PrevID;
        ADOCommand1.Execute;

        ADODataSet1.Requery([]);
    end;
end;
0 голосов
/ 03 февраля 2011

Я верю, что это сделает это за вас ...

update P_Columns 
set Column_Order = ((select count(*) from P_Columns) + 1) - Column_Order 
...