2015-02-02 1 views
2

Как создать ограничение функции для денормализованных данных?Ограничение функции SQL для денормализованных данных

-- graduation_class table 
graduation_class_id | graduation_year_id 
123       1  
456       2 

-- user table 
user_id | graduation_class_id | graduation_year_id 
555    123      1 
556    123      3 <--- bad data 
557    456      2 

Класс окончания может быть присвоен только году окончания знака. Комбинация этих двух уникальна в таблице graduation_class.

Я хочу создать ограничение функции в столбце graduation_year_id в таблице пользователя, чтобы убедиться, что функция graduation_year_id синхронизируется с соответствующим идентификатором из таблицы graduation_class, так что запись 556 в таблице пользователя никогда не произойдет.

** Пожалуйста, примите во внимание, что нормализация НЕ является решением этого вопроса, или я бы не стал задавать этот вопрос! :) **

+0

ли 'graduation_class_id + graduation_year_id' является уникальным в' graduation_class' таблица –

+0

Да, это уникальное сочетание в таблицу градуировки_класса. –

+0

То, что вы хотите достичь, лучше всего реализовать с помощью ограничения FK –

ответ

1

Как уже упоминалось в других ответах, эта схема не идеально, но если вам нужно сохранить целостность данных в этой схеме, прежде чем иметь возможность очистить вещи, ограничение функции сделает это за вас. Во-первых, мы создадим функцию, которая принимает в graduation_class_id и graduation_year_id в качестве параметров, и возвращает значение бита:

create function dbo.fn_check_graduation_year_id 
    (
    @graduation_class_id int, 
    @graduation_year_id int 
    ) 
    returns bit 
as 
    begin 
     declare @return bit = 1 
     if @graduation_year_id != (select top 1 graduation_year_id 
            from graduation_class 
            where graduation_class_id = @graduation_class_id) 
      set @return = 0 
     return @return 
    end 

Эта функция возвращает истину, если graduation_year_id соответствует значению на graduation_class таблице присваивают значение graduation_class_id. Далее, мы добавим ограничение на ваш user таблицы, убедившись, что результат функции проверки возвращает истину:

alter table [user] with nocheck add constraint ck_graduation_year_id 
    check (dbo.fn_check_graduation_year_id(graduation_class_id,graduation_year_id) = 1) 
+0

см. Здесь http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be-careful-with-constraints-calling-udfs.aspx –

+0

В этом случае функция принимает оба значения, которые проверяются , поэтому обновление для того, что не соответствует таблице «graduation_class», приведет к ошибке. Не идеальное решение, но ответ на OP не меньше. –

0

Как это:

alter table user 
drop column graduation_year_id 

Если вам это нужно, выбрать его путем присоединения к столу graduation_year

+0

Это идеальное решение, но сейчас мы нуждаемся в его денормализации ... есть ли хороший способ заставить это работать, предполагая, что нам нужно он денормализован? –

+0

Используйте триггер для обновления столбца. –

1

Вместо функции создания composite primary key и foreign key исправить вашу проблему

Изготовление graduation_class_id ,graduation_year_id в graduation_class как составной primary key

ALTER TABLE graduation_class 
ADD PRIMARY KEY (graduation_class_id ,graduation_year_id) 

Теперь добавьте foreign key в таблице пользователей

ALTER TABLE user 
ADD FOREIGN KEY (graduation_class_id ,graduation_year_id) 
REFERENCES graduation_class(graduation_class_id ,graduation_year_id) 

Это позволит вам добавить только строку добавлен в user таблицу уже присутствует в graduation_class таблице

+0

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

+0

@DavidFaber Может быть .. но это не тот правый столбец, который должен действовать как первичный ключ в этой таблице, должен быть изменен –

+0

Вам не нужно изменять 'gradation_class' PK. Единственное ограничение на оба столбца ('graduation_class_id, graduation_year_id'). –

Смежные вопросы