Xpoint
   [напомнить пароль]

изменение IDENTITY PRIMARY KEY

Метки: [без меток]
[арх]
2005-11-22 17:31:06 [обр] Евгения Фирсова aka saigo[досье]

Есть таблица MyTable, у которой поле задано так:
uid INT IDENTITY(1,1) PRIMARY KEY

Есть также несколько других таблиц, у которых есть поля вида:
nid INT REFERENCES MyTable

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

Теперь мне нужно разово изменить имеющиеся в таблице uid.
Каскадирование изменений - включено.

Моя неудачная попытка:
SET IDENTITY_INSERT News ON
UPDATE MyTable SET uid = 111 WHERE uid = 11
SET IDENTITY_INSERT News OFF
DBCC CHECKIDENT (MyTable,RESEED,112)

Как всё же изменить значения uid?

спустя 2 часа 19 минут [обр] GRAy(8/259)[досье]
ИМХО, если действие разовое: отключить ограничения целостности, проапдейтить все таблицы, включить ограничение. Команды соотв. зависят от вашей СУБД. Делать разумеется ночью, когда пользователей нет, если такое не возможно... всё на порядки сложнее и опять же сильна специфика вашей СУБД. Что вы используете?
спустя 13 часов [обр] Евгения Фирсова aka saigo[досье]
Использую MSSQL.
Да, ночью - это понятно, хотя и сложно осуществимо на практике.
Но возможно ли решить задачу не меняя структуру таблиц (не отключая ограничения целостности)?
спустя 1 час 33 минуты [обр] GRAy(8/259)[досье]

Евгения Фирсова aka saigo[досье] Отключение ограничений целостности - это не изменение структуры таблиц, это всего навсего указание СУБД не проверять некие предусловия при вставке, удалении и изменении данных в таблице. К сожалению не знаю как это делается в MSSQL, но стандартный синтаксис по идее следующий:

/* отключаем ограничение */
ALTER TABLE MyTable DISABLE CONSTRAINT Constraint_name;
/* включаем ограничение */
ALTER TABLE MyTable ENABLE CONSTRAINT Constraint_name;

Данные команды должны действовать на любые ограничения которые могут быть наложены на таблицы, т.е. на Primary key, Foreign key, Unique Key и т.п.
Самое нетривиальное в данной ситуации это выяснить имя ограничения, т.к. зачастую, при создании таблиц, вы их явно не называете (что кстати плохая практика) и СУБД делает это за вас. Название которое получается в итоге совершенно нечитабельно, и ничего не говорит о том, к каким таблицам оно относится. Искать надо в словаре данных, можно селектами, а можно с помощью тех программ которыми вы обычно пользуетесь для разработки transact SQL - скорее всего они имеют такую возможность (и может быть даже могут отключать, включать эти ограничения). Как правило, для PK и UK ещё дополнительно создаётся индекс, который может мешать вставке неуникальных значений в поле первичного/уникального ключа, но в вашем случае, я думаю, это не играет никакой роли.

спустя 12 минут [обр] GRAy(8/259)[досье]
А вот и синтаксис для MSSQL:
/* отключаем */
ALTER TABLE MyTable NOCHECK CONSTRAINT Constraint_name;
/* включаем */
ALTER TABLE MyTable CHECK CONSTRAINT Constraint_name;
спустя 2 часа 1 минуту [обр] Кирилл [Kirk] Королев(88/673)[досье]
GRAy[досье] это не сработает.
Евгения Фирсова aka saigo[досье] нельзя это сделать средствами T-SQL/DMO, только руками снять галку Identity в EM, имхо.
http://support.microsoft.com/default.aspx?scid=kb;en-us;820675
спустя 13 дней [обр] Алексей Рюмин aka Dwarf(18/864)[досье]

Кирилл [Kirk] Королев[досье]

только руками снять галку Identity в EM, имхо.

При этом будет следующее:

  1. Создана временная таблица
  2. Все данные из основной будут вставлены во временную с таблоком.
  3. Дропнуты все констрэйны основной таблицы.
  4. Дропнута основная таблица.
  5. Воссоздана основная таблица без IDENTITY.
  6. Вставлены данные.
  7. Созданы констрэйны.
  8. Дропнута временная таблица.

Профайлер рулит :)

спустя 2 часа 2 минуты [обр] GRAy(8/259)[досье]
Алексей Рюмин aka Dwarf[досье] Афигеть ;)
спустя 16 часов [обр] Кирилл [Kirk] Королев(88/673)[досье]
Алексей Рюмин aka Dwarf[досье] Йоу. Интересно, а посложнее процедуру они придумать не могли? =) Все это, конешно, можно и самому написать.
спустя 1 день 3 часа [обр] Алексей Рюмин aka Dwarf(18/864)[досье]
Кирилл [Kirk] Королев[досье] А чего тут сложного? :) Foreign key(s) надо дропать и создавать заново по-любому... Потом пересоздавать таблицу... Сейчас с другой таблицей посмотрел - почему-то создал новую, перенес данные, старую дропнул и новую переименовал. О как :)
Powered by POEM™ Engine Copyright © 2002-2005