Есть ли умный способ добавить число в столбец идентификации PK в реляционной базе данных без полной катастрофы? - PullRequest
3 голосов
/ 18 мая 2011

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

Есть ли лучший способ сделать это?

Ответы [ 5 ]

2 голосов
/ 18 мая 2011

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

Если для ваших отношений установлены каскадные обновления, остальные таблицы должны обновляться автоматически.

РЕДАКТИРОВАТЬ: Поскольку невозможно изменить значение идентификатора Я думаю, вам нужно экспортировать данные, установить новые значения идентификаторов (+10000)и затем импортируйте ваши данные снова.

У кого-нибудь есть лучшее предложение ...

1 голос
/ 18 мая 2011

Если у рассматриваемого столбца есть свойство тождественности, оно усложняется.Это более или менее так:

  • Резервное копирование вашей базы данных.

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

  • Выполните ALTER TABLE операторы, необходимые для

    • , отключите ограничение первичного ключа нарассматриваемая таблица
    • отключить все триггеры в рассматриваемой таблице
    • отключить все ограничения внешнего ключа, ссылающиеся на обсуждаемую таблицу.
  • Cloneваша таблица, давая ей новое имя и столбец для столбца идентичные определения.Не беспокойтесь о каких-либо триггерах, индексах, внешних ключах или других ограничениях.Опустите свойство identity из определения таблицы.

  • Создайте новую таблицу 'map', которая будет сопоставлять ваши старые значения идентификатора с новым значением:

    create table dbo.pk_map
    (
      old_id int not null primary key clustered ,
      new_id int not null unique nonclustered ,
    )
    
  • Заполните таблицу карт:

    insert dbo.pk_map
    select old_id = old.id ,
           new_id = f( old.id ) // f(x) is the desired transform
    from dbo.tableInQuestion old
    
  • Заполните новую таблицу, указав в столбце первичного ключа новое значение:

    insert dbo.tableInQuestion_NEW
    select id = map.id ,
           ...
    from dbo.tableInQuestion old
    join dbo.pk_map          map on map.old_id = old.id
    
  • Сокращение исходной таблицы: TRUNCATE dbo.tableInQuestion.Это должно работать - безопасно - так как вы отключили все триггеры и ограничения внешнего ключа.

  • Выполните SET IDENTITY_INSERT dbo.tableInQuestion ON.

  • Перезагрузитеисходная таблица:

    insert dbo.tableInQuestion
    select *
    from dbo.tableInQuestion_NEW
    
  • Выполнить SET IDENTITY_INSERT dbo.tableInQuestion OFF

  • Выполнить drop table dbo.tableInQuestion_NEW.Мы все с этим покончили.

  • Выполните DBCC CHECKIDENT( dbo.tableInQuestion , reseed ), чтобы синхронизировать счетчик идентификаторов с данными в таблице.

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

  • Когда все будет готово, начните повторное включениеограничения и триггеры вы отключили.Убедитесь, что вы делаете это, используя опцию WITH CHECK.Исправьте все обнаруженные проблемы.

  • Наконец, отбросьте таблицу карт, снимите флажок с одного пользователя и верните вашу систему (-ы) в оперативный режим.

Кусок торта!(или что-то.)

1 голос
/ 18 мая 2011

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

1 голос
/ 18 мая 2011

Мое предложение:

  1. Прекратить запись в таблицы.
  2. Скопируйте таблицы в новые таблицы с новым PK.
  3. Переименуйте старые таблицы в имена резервных копий.
  4. Переименуйте новые таблицы в исходное имя таблицы.
  5. Подсчитайте строки во всех таблицах и дважды проверьте свою работу.
  6. Продолжайте использовать таблицы.

Смена PK после факта - это не весело.

0 голосов
/ 18 мая 2011

Рассмотрите этот подход: сбросьте начальное число идентификаторов на 10000 + текущее начальное число.Установите идентификатор вставки на Вставить в таблицу из значений в таблице и добавьте 10000 в столбец идентификаторов на пути.Пример:

Set identity insert on
Insert Table(identity, column1, eolumn2)
select identity + 10000, column1, column2
From Table
Where identity < origional max identity value

После вставки вы знаете, что личность на 10000 больше, чем оригинал.Обновите внешние ключи, добавив 10000.

...