Как обновить таблицу SQL уникальным номером в диапазоне - PullRequest
1 голос
/ 25 ноября 2011

(Это продолжение ответа "onedaywhen" на вопрос , который я разместил ранее сегодня.)

Привет всем.Скажем, у меня есть таблица MyTable с двумя int полями, PrimaryKey и MyNumber.(И другие поля, не имеющие прямого отношения к этому вопросу).MyNumber имеет уникальное ограничение и ограничение проверки, ограничивающее его до BETWEEN 1 AND n.(Допустим, на данный момент n=5.)

1,2  
2,NULL  
3,5  
4,NULL  
5,NULL  
6,1  
7,NULL

Как можно написать UPDATE, чтобы изменить запись, где PrimaryKey=2, чтобы MyNumber имел значение, отличное от NULL?Мне все равно, какое значение оно имеет, если оно не NULL и соответствует двум ограничениям уникальности и находится в пределах досягаемости.

Я использую MS SQL Server, но надеюсь,есть ответ с использованием стандартного SQL.

(я также надеюсь, что не будет таблицы с номерами от 1 до n в качестве содержимого.)

Большое спасибо.

Ответы [ 3 ]

0 голосов
/ 25 ноября 2011
WITH CTE AS (
    SELECT 1 N
    UNION ALL
    SELECT N + 1 FROM CTE WHERE N < 5
)
UPDATE MyTable
SET MyNumber = (
    SELECT TOP 1 N FROM CTE
    WHERE NOT EXISTS (SELECT * FROM MyTable WHERE MyNumber = N)
)
WHERE PrimaryKey = 2

Простым английским языком:

  • Генерация целых чисел от 1 до 5 (WITH CTE AS ...).
  • Выберите первое из этих целых чисел, которое не уже существует в MyNumber (SELECT TOP 1 ...).
  • Присвойте это целое число MyNumber в строке, обозначенной PrimaryKey = 2 (UPDATE ...).

Если этот запрос не может найти подходящее значение, он просто установит для MyNumber значение NULL.


ПРЕДУПРЕЖДЕНИЕ. Это может по-прежнему нарушать УНИКАЛЬНОЕ ограничение для MyNumber в параллельной среде (то есть, когда две одновременно выполняющиеся транзакции пытаются выполнить этот же запрос параллельно). Таким образом, вы должны быть готовы повторить запрос в случае необходимости.

0 голосов
/ 26 ноября 2011

Не могу не отметить, что следующая версия SQL (кодовое имя Denali) будет поддерживать SEQUENCES, что в данном случае явно идеально.

Код будет выглядеть примерно так:

CREATE SEQUENCE Count1to5
  START WITH 1
  INCREMENT BY 1
  MAX VALUE 5;

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

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

Посмотрите на функцию @ROW_NUMBER для MS-SQL, я не могу не думать о коде прямо сейчас, и я не рядом с моим сервером БД, чтобы выполнить некоторые тесты, но если память не изменяет, @ROW_NUMBER в сочетании с проверкой «IS NOT NULL» должны помочь вам достичь вашей цели.

@ ROW_NUMBER документация: http://msdn.microsoft.com/en-us/library/ms186734.aspx

Для других разновидностей SQL я не могу придумать решениев настоящее время.

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