Обновление нескольких строк, конфликтующих с уникальным индексом - PullRequest
4 голосов
/ 07 апреля 2010

Я использую Microsoft SQL Server, и у меня есть сценарий master-detail, где мне нужно хранить порядок деталей. Итак, в таблице сведений у меня есть ID, MasterID, Position и некоторые другие столбцы. Существует также уникальный индекс MasterID и Position. Это работает хорошо, за исключением одного случая: когда у меня есть некоторые существующие детали, и я меняю их порядок. Например, когда я меняю деталь в позиции 3 на деталь в позиции 2. Когда я сохраняю деталь в позиции 2 (которая в базе данных имеет позицию, равную 3), SQL Server протестует, потому что ограничение уникальности индекса

Как решить эту проблему разумным путем?

Заранее спасибо
Лукаш Глаз

Ответы [ 2 ]

1 голос
/ 07 апреля 2010

Это классическая проблема, и ответ прост: если вы хотите переместить элемент 3 в позицию 2, вы должны сначала изменить столбец сортировки 2 на временное число (например, 99). Так это выглядит так:

Move 2 to 99
Move 3 to 2
Move 99 to 3

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

Обновление : Кстати - один из способов справиться с проблемой «несколько пользователей могут менять порядок» - это сделать то, что я делаю: дать каждому пользователю цифровой идентификатор, а затем добавить его к временному номеру (мой идентификатор персонала на самом деле является идентификатором поля «Уникальный идентификатор» из таблицы персонала, используемой для входа в систему). Так, например, если ваши позиции никогда не будут отрицательными, вы можете использовать -1000 - UserID в качестве временного значения. Но поверь мне в одном: ты не хочешь просто предположить, что у тебя никогда не будет столкновения. Если вы думаете, что один действительно произойдет, отладку будет крайне сложно!

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

Во-первых, вы можете изменить существующие поля сортировки всего набора на новый набор не сталкивающихся значений (например, -100 - (staffID * maxSetSize) +istingOrderVal), а затем перейти к записи по записи и изменить каждую запись. на новую стоимость заказа.

Или вы можете по существу рассматривать его как пузырьковую сортировку в массиве, где значение orderVal является эквивалентом индекса вашего массива. Либо это имеет смысл для вас (и очевидно), либо вам следует придерживаться решения 1 (которое легче в любом случае).

0 голосов
/ 07 апреля 2010

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

...