Обновление записей базы данных с уникальным ограничением - PullRequest
3 голосов
/ 25 января 2011

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

CREATE TABLE MYLIST(
      ID int NOT NULL IDENTITY(1, 1)
    , TITLE varchar(50) NOT NULL
    , SEQUENCE int NOT NULL
    , CONSTRAINT pk_mylist_id PRIMARY KEY(ID)
    , CONSTRAINT uq_mylist_sequence UNIQUE(SEQUENCE)
);

Мой интерфейс позволяет мне смешивать порядок элементов, и Я буду знать перед выполнением обновления, какая непересекающаяся последовательность должна быть в , но как мне выполнить обновление без столкнулись с нарушением уникального ограничения?

Например, скажем, у меня есть эти записи:

ID  TITLE   SEQUENCE
1   APPLE   1
2   BANANA  2
3   CHERRY  3

И я хочу обновить их порядковые номера следующим образом:

ID  TITLE   SEQUENCE
1   APPLE   3
2   BANANA  1
3   CHERRY  2

Но на самом деле я мог бы иметь дело с парой дюжин предметов. Порядковые номера не должны пересекаться. Я думал о попытке использовать триггеры или временно отключить ограничение, но это может создать больше проблем. Я использую C # и LINQ-to-SQL, но открыт только для решений в области баз данных.

Ответы [ 3 ]

3 голосов
/ 25 января 2011

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

Запись строка за строкой не имеет смысла и вызывает вашу проблему.

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

DECLARE @NewSeq TABLE (ID int, NewSeq int)

INSERT @NewSeq (ID, NewSeq) VALUES (1, 3)
INSERT @NewSeq (ID, NewSeq) VALUES (2, 1)
INSERT @NewSeq (ID, NewSeq) VALUES (3, 2)

UPDATE
   M
SET
   SEQUENCE = NewSeq
FROM
   MYLIST M
   JOIN
   @NewSeq N ON M.ID = N.ID
2 голосов
/ 25 января 2011

Вы можете присвоить им отрицательное их правильного значения, а затем, после того как произойдут все обновления, выполнить окончательное обновление, установив SEQUENCE = -SEQUENCE.

Это не очень эффективно, но, поскольку вы говорите, что у вас всего пара десятков предметов, я сомневаюсь, что воздействие будет заметным. Я также предполагаю, что вы можете использовать отрицательные числа в качестве «магических значений» для указания временно неправильно назначенных значений.

0 голосов
/ 25 января 2011

Если вы действительно должны следовать этому рабочему процессу вставки, не зная правильного порядка, а затем возвращаться с обновлением позже, чтобы установить правильный порядок, я бы сказал, что ваш лучший вариант - избавиться от уникального ограничения, потому что это вызывает у вас больше проблем, чем оно того стоит. Конечно, только вы знаете, сколько это уникальное ограничение «стоит» для вашего приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...