Предыстория
На работе, где мы планируем исключить столбец Natural Key в одной из наших основных таблиц.Проект состоит из более 100 приложений, которые ссылаются на эту таблицу / столбец;400+ хранимых процедур, которые напрямую ссылаются на этот столбец;и обширный массив общих таблиц между этими приложениями, которые также ссылаются на этот столбец.
Методы Большого взрыва и Начать с нуля находятся вне поля зрения.Мы собираемся осудить этот столбец по одному приложению за раз, сертифицировать изменения и перейти к следующему ... и у нас есть длинная цель, чтобы сделать это усилие практичным.
ПроблемаУ меня есть то, что многие из этих приложений имеют общие хранимые процедуры и таблицы.Если я полностью сконвертирую все таблицы / хранимые процедуры Приложения A, Приложения B и C будут прерваны до преобразования.Это, в свою очередь, может сломать приложения D, E, F ... и т. Д.У меня уже есть стратегия, реализованная для классов кода и хранимых процедур, часть, на которой я застрял, - это переходное состояние базы данных.
Вот пример basic того, что мы имеем:
Users
---------------------------
Code varchar(32) natural key
Access
---------------------------
UserCode varchar(32) foreign key
AccessLevel int
И сейчас мы стремимся только к переходному состоянию, как это:
Users
---------------------------
Code varchar(32)
Id int surrogate key
Access
---------------------------
UserCode varchar(32)
UserID int foreign key
AccessLevel int
Идея, заключающаяся в том, что во время переходного этапа неперемещенные приложения и хранимые процедуры все еще будут в состояниичтобы получить доступ ко всем соответствующим данным, а новые можно начинать нажимать на правильные столбцы. После завершения миграции для всех хранимых процедур и приложений мы можем, наконец, удалить дополнительные столбцы.
Я хотел использовать триггеры SQL Server.чтобы автоматически перехватить любую новую вставку / обновление и выполнить что-то вроде следующего для каждой из затронутых таблиц:
CREATE TRIGGER tr_Access_Sync
ON Access
INSTEAD OF INSERT(, UPDATE)
AS
BEGIN
DIM @code as Varchar(32)
DIM @id as int
SET @code = (SELECT inserted.code FROM inserted)
SET @id = (SELECT inserted.code FROM inserted)
-- This is a migrated application; find the appropriate legacy key
IF @code IS NULL AND @id IS NOT NULL
SELECT Code FROM Users WHERE Users.id = @id
-- This is a legacy application; find the appropriate surrogate key
IF @id IS NULL AND @code IS NOT NULL
SELECT Code FROM Users WHERE Users.id = @id
-- Impossible code:
UPDATE inserted SET inserted.code=@code, inserted.id=@id
END
Вопрос
2 огромные проблемы, с которыми я столкнулсядо сих пор:
- Я не могу сделать «ПОСЛЕ ВСТАВКИ», потому что ограничения NULL приведут к ошибке вставки.
- Упомянутый мною «невозможный код» - это то, как я хотел бы чисто прокси-сервер исходного запроса;Если в исходном запросе есть столбцы x, y, z или просто x, в идеале я бы хотел, чтобы тот же триггер делал это.И если я добавлю / удалю другой столбец, я бы хотел, чтобы триггер оставался работоспособным.
У всех есть пример кода, где это возможно, или даже альтернативное решение для правильного заполнения этих столбцов.даже когда в SQL передается только одно из значений?