Установка правильного внешнего ключа на вставке - PullRequest
1 голос
/ 09 декабря 2011

Утро всем,

Я проделываю большую работу, чтобы перетащить базу данных (SQL Server 2005, в режиме совместимости с 2000), пиная и крича, чтобы получить разумный дизайн.

В настоящий момент все первичные ключи всех таблиц имеют значение nvarchar(32) и задаются с помощью uniqId() (как ни странно, это запускается через специальную функцию хеширования, не знаю почему)

Итак, в несколько этапов я делаю некоторые фундаментальные изменения:

  1. Представление столбцов ID_int для каждой таблицы, автоинкремент и первичный ключ
  2. Добавление дополнительной индексации, удаление неиспользуемых индексов, удаление неиспользуемых столбцов

До сих пор этот этап работал хорошо, тестовая база данных выглядит немного быстрее, общий размер индексов для каждой таблицы НАМНОГО меньше.

Моя проблема со следующим этапом: внешние ключи. Мне нужно иметь возможность установить эти INT внешние ключи при вставке в другие таблицы.

Есть несколько приложений, указывающих на эту БД, только одно из которых я контролирую. Он также содержит много сохраненных процедур и триггеров.

Я не могу физически внести все необходимые изменения за один раз.

Итак, я хотел бы иметь возможность добавлять целочисленные FK в каждую таблицу и автоматически устанавливать их на нужную вещь при вставке.

Чтобы проиллюстрировать это на примере:

Две таблицы, Call и POD, связанные pod.Call_ID -> Call.Call_ID. Это поле nvarchar(32).

Я изменил вызов так, что Call_ID_int это идентификатор, автоинкремент, первичный ключ. Мне нужно добавить POD.Call_ID_int так, чтобы при вставке он получал правильное значение от Call.Call_ID_int.

Я уверен, что мог бы сделать это с помощью ПЕРЕД триггером, но я бы предпочел избежать этого по причинам обслуживания и скорости.

Я думал, что смогу сделать это с ограничением, но после долгих исследований не смог. Я попробовал это:

alter table POD
add constraint
pf_callIdInt
default([dbo].[map_Call_ID_int](Call_ID))
for Call_ID_int

Где функция map_Call_ID_int принимает Call_ID и возвращает правильное значение Call_ID_int, но я получаю эту ошибку:

Имя "Call_ID" не разрешено в этом контексте. Допустимые выражения являются константами, константными выражениями и (в некоторых контекстах) переменными. Имена столбцов не допускаются.

Есть идеи, как мне этого добиться?

Заранее большое спасибо!

-Oli

1 Ответ

2 голосов
/ 09 декабря 2011

Триггеры - самый простой способ.

У вас будут странные проблемы параллелизма со значениями по умолчанию, основанными на UDF (как и в случае ограничений CHECK).

Еще один прием - использовать представления, чтобы скрыть изменения схемы, но при этом использовать триггеры для перехвата DML. Таким образом, ваша «старая» таблица больше не существует только как представление «новой» таблицы. Запись в «старую» таблицу / представление фактически происходит на новой таблице.

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