4

Учитывая следующую простую структуру таблиц (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, но я открыт для строго баз данных решений.

+0

Можете ли вы уточнить в одном заявлении? – gbn

+0

У меня есть свобода попробовать что угодно, если это ответит на ваш вопрос. – JustinStolle

ответ

2

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

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

+0

Мне нравится простота этого и на самом деле подумала об этом через несколько минут после публикации вопроса. Для моей ситуации это может иметь наибольший смысл. – JustinStolle

+0

Хммм ... ничего не мешает кому-то вводить отрицательное число непосредственно в базу данных, что нарушит это решение. –

3

Очевидным способом является запись в виде одной партии. Внутренне 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 
+0

Это, кажется, технически правильное решение с наименьшим шансом на ошибку, хотя для этого потребуется дополнительный код. Для моих целей достаточно трюк отрицательного числа Дэйва. – JustinStolle

0

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

+0

Я знаю правильный или желаемый порядок раньше времени до обновления. – JustinStolle

+0

Правильно, но вы не знаете правильный порядок перед вставкой, правильно? –

+0

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

Смежные вопросы