SQL, Как изменить столбец в таблице SQL, не нарушая других зависимостей?
Я уверен, что это может быть довольно распространенный запрос, но пока не смог найти хорошего ответа.
Вот мой вопрос:
У меня есть таблица с названием Контакты с заголовком varchar. Сейчас, в середине разработки, я хочу заменить поле Title на TitleID, который является внешним ключом таблицы ContactTitles. На данный момент таблица Contacts имеет более 60 зависимостей (другие таблицы, функции представлений).
Как я могу сделать это самым безопасным и простым способом?
Мы используем: MSSQL 2005, данные уже перенесены, просто хотим изменить схему.
Редактировать:
Спасибо всем за быстрое воспроизведение.
Как уже упоминалось, в таблице контактов более 60 зависимых, но при выполнении следующего запроса только 5 из них используют столбец заголовка. Сценарий миграции был запущен, поэтому никаких изменений данных не требуется.
/*gets all objects which use specified column */
SELECT Name
FROM syscomments sc
JOIN sysobjects so ON sc.id = so.id
WHERE TEXT LIKE '%Title%' AND TEXT LIKE '%TitleID%'
Затем я просмотрел эти 5 просмотров и обновил их вручную.
4 ответа
Для Microsoft SQL Server Redgate есть (не бесплатный) продукт, который может помочь с этим рефакторингом http://www.red-gate.com/products/sql_refactor/index.htm
В прошлом мне удавалось сделать это довольно легко (если примитивно), просто получив список вещей для обзора
SELECT * FROM sys.objects
WHERE OBJECT_DEFINITION(OBJECT_ID) LIKE '%Contacts%'
(и, возможно, с учетом информации о зависимостях и фильтрации по типу объекта)
Написание сценариев для всех интересующих вас компонентов в Management Studio, затем просто спуститься по списку, просмотреть их все и изменить CREATE на ALTER. Это должно быть довольно простое и повторяющееся изменение даже для 60 возможных зависимостей. Кроме того, если вы ссылаетесь на несуществующий столбец, вы должны получить сообщение об ошибке при запуске сценария для ALTER.
Если вы используете *
в ваших запросах или adhoc SQL в ваших приложениях, очевидно, все может быть немного сложнее.
Используйте методы рефакторинга. Начните с создания нового поля с именем TitleID
затем скопируйте все заголовки в ContactTitles
Таблица. Затем по одному обновите каждую из зависимостей, чтобы использовать поле TitleID. Просто убедитесь, что у вас все еще есть работающая система после каждого шага.
Если данные будут меняться, вы должны быть осторожны и следить за тем, чтобы любые изменения в Title
столбец также изменить ContactTitles
Таблица. Вам нужно будет только синхронизировать их во время рефакторинга.
Редактировать: Есть даже книга об этом! Рефакторинг баз данных.
Как отмечали другие, это зависит от вашей РСУБД.
Есть два подхода:
- внести изменения в таблицу и исправить все зависимости
- создайте представление, которое вы можете использовать вместо прямого доступа к таблице (это может защитить вас от будущих изменений в базовой базовой таблице (таблицах), но вы можете потерять некоторые функции обновления, в зависимости от вашей СУБД)
Используйте SP_Depend 'Table Name', чтобы проверить зависимости таблицы, а затем используйте SP_Rename, чтобы переименовать имя столбца, что очень полезно. sp_rename автоматически переименовывает связанный индекс всякий раз, когда ограничение PRIMARY KEY или UNIQUE переименовывается. Если переименованный индекс связан с ограничением PRIMARY KEY, ограничение PRIMARY KEY также автоматически переименовывается в sp_rename.
и затем начните Обновлять Процедуру и Функции одну за другой, нет другого хорошего варианта для изменения как этот, если Вы нашли, тогда скажите мне также.