Как сохранить изменения в последовательном списке имен в базе данных sql?

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

Учитывая упорядоченный список имен и пользовательский интерфейс, где пользователь может переупорядочивать, удалять, редактировать и добавлять имена в список, как бы вы обновили список, хранящийся в базе данных SQL?

Вот определение таблицы:

CREATE TABLE [dbo].[AssyLines](
  [AssyLineID] [int] IDENTITY(1,1) NOT NULL,
  [ShortName] [varchar](16) NOT NULL,
  [LongName] [varchar](45) NOT NULL,
  [Seq] [tinyint] NOT NULL,
CONSTRAINT [PK_AssyLines] PRIMARY KEY CLUSTERED 

Что я хочу сделать, это прочитать все записи из таблицы и отобразить их в порядке следования в пользовательском интерфейсе. Затем пользователь может отредактировать ShortName или LongName, изменить порядок списка, добавить новые записи или удалить существующие записи, а затем сохранить измененный список обратно в базу данных.

Это клиент-серверное приложение, если это имеет значение. Служба WCF обрабатывает взаимодействие с базой данных, а клиент просто отправляет массив записей в службу и из службы.

Мой метод грубой силы включает блокировку таблицы, удаление всех записей, а затем перезапись новых записей в таблицу - все внутри транзакции, конечно, с использованием хранимой процедуры и либо табличной переменной, либо временной таблицы. Грубый, но эффективный, но я не могу удержаться от ощущения, что есть довольно стандартный способ сделать это, не взламывая таблицу и не воссоздавая ее каждый раз, когда кто-то вносит незначительные изменения.

Есть идеи? У меня есть 4 или 5 таких списков в приложении, над которым я сейчас работаю.

Спасибо дэйв

3 ответа

Решение

Почему бы просто не выполнить запрос UPDATE для каждой записи (идентифицируемой AssyLineID, которая не должна изменяться), которая обновляет другие столбцы в соответствии с тем, что указал пользователь? Не нужно ничего удалять, и вы можете уменьшить количество операций с БД, отслеживая то, что изменил пользователь.

Если вы беспокоитесь о переупорядочении Seq часть, я думаю, что это будет работать для этого:

if (newSeq < oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq + 1 WHERE Seq >= @seq AND Seq < @oldSeq AND AssyLineID <> @lineID";
}
else if (newSeq > oldSeq)
{
    sql = "UPDATE AssyLines SET Seq = Seq - 1 WHERE Seq <= @seq AND Seq > @oldSeq AND AssyLineID <> @lineID";
}

Может быть, я не понимаю, почему вы чувствуете, что вам нужно каждый раз обстреливать стол. Это звучит как ваша основная операция выбора-изменения-сохранения, кроме части Seq.

Подход, который я выбрал бы, заключается в том, чтобы использовать первичный ключ, чтобы связать обновления, вставить и удалить изменения и сделать пару проходов по данным.

  1. Загрузите список из базы данных в пользовательский интерфейс и сохраните идентификатор для элемента. Кроме того, храните "измененный" флаг, который изначально установлен в false для каждого элемента.
  2. Внесите любые изменения в данные в пользовательском интерфейсе следующим образом:
    • Добавляет данные, добавляя их, устанавливая ID (первичный ключ) в -1, а измененный флаг в значение true.
    • Обновляет данные, редактируя их, устанавливая для измененного флага значение true.
    • Удаляет из данных, просто удаляя их.
  3. Выполните итерацию по каждому элементу в списке, где измененный флаг =true, и выполните следующее:
    • Если ID = -1, то добавьте новую запись, используя INSERT.
    • Если ID > -1, обновите существующую запись, совпадая с идентификатором и записью, которую вы хотите обновить, используя UPDATE.
  4. Затем перечитайте все идентификаторы записей, которые существуют в базе данных, просматривайте каждую из них и проверяйте список, чтобы увидеть, существует ли он. Если нет, то удалите его из базы данных, используя DELETE.

Шаг 4 может стать довольно медленным, если у вас много данных. Несколько иной, более эффективный способ будет зависеть от того, можно ли "пометить" запись как удаленную в пользовательском интерфейсе и скрыть ее от просмотра, не удаляя ее. Затем вы можете заменить измененный флаг на статус, который либо установлен в "I", "U" или "D", в зависимости от того, является ли он вставкой, обновлением или удалением. Тогда вам понадобится только один проход через данные.

Я не являюсь разработчиком.NET, но еще один элегантный способ сделать это состоит в том, чтобы иметь 3 слушателей на столе; прослушиватель добавления, прослушиватель обновлений и прослушиватель удаления. Слушатели будут вызывать INSERT, UPDATE и DELETE соответственно.

Сортировка списка не влияет на данные, хранящиеся в базе данных.

Другие вопросы по тегам