Ограничение базы данных для проверки конкретных ограничений, зависящих от входного значения? - PullRequest
0 голосов
/ 25 октября 2010

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

Существует таблица ведения журнала, в которой есть столбец ParentID и столбец ParentType. Запись в столбце ParentType определяет таблицу, на которую ссылается ParentID.

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

Я бы хотел иметь возможность просто выбросить весь задний план этой программы и начать заново, но это уже чертовски ненадежно, и я не сломаю все . Затягивание бэк-энда, похоже, лучший из моих лучших на данный момент. Кажется, единственная реальная альтернатива - это выбросить всю программу.

Итак, да, идеи о наилучшем способе ограничения данных в этом столбце на стороне SQL?

РЕДАКТИРОВАТЬ: я могу сказать это неясно уже ...

Правильно, у меня есть таблица регистрации, затем TableOne и TableTwo. Если строка, вводимая в Logging, пытается добавить строку с 1 в столбце ParentType, тогда ParentID должен появиться в TableOne, если ParentType равен 2, ParentID должен появиться в TableTwo.

Ответы [ 3 ]

1 голос
/ 25 октября 2010

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

1 голос
/ 25 октября 2010

Создайте два постоянных вычисляемых столбца, например:

CarID AS (CASE WHEN Type='Car' THEN ParentID END)

TruckID AS (CASE WHEN Type='Truck' THEN ParentID END)

и пусть FK отсылает их к вашим таблицам.

1 голос
/ 25 октября 2010

Лучше всего будет реализовать это правило в качестве триггера INSTEAD OF в таблице журналов, где вы можете сравнить идентификаторы с соответствующей таблицей и отклонить INSERT / UPDATE, если произойдет нарушение FK. В грубом псевдокоде, что-то вроде:

CREATE TRIGGER tr_io_iu_Logging ON Logging
INSTEAD OF INSERT, UPDATE
AS
BEGIN
    IF UPDATE(ParentID) BEGIN
        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableOne t1 ON i.ParentID = t1.ID WHERE i.ParentType=1 AND t1.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */

        IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableTwo t2 ON i.ParentID = t2.ID WHERE i.ParentType=2 AND t2.ID IS NULL)
            /* perform the insert */
        ELSE 
           /* raise error */
    END /* IF */    
END /* trigger */
...