如何为非规范化数据创建函数约束?
-- 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
毕业班只能分配到毕业年份。这两者的组合在gradu_class表中是唯一的。
我想在user表的gradu_year_id列上创建一个函数约束,以确保gradu_year_id与gradu_class表中的正确id同步,以便用户表中的记录556永远不会发生。
**请假设标准化不是解决方案,或者我不会问这个问题! :) **
答案 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
表
答案 1 :(得分: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
表上的值匹配,则此函数将返回true。接下来,我们将约束添加到您的user
表中,确保check函数的结果返回true:
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)
答案 2 :(得分:0)
像这样:
alter table user
drop column graduation_year_id
如果您需要,请通过加入gradu_year表
来选择它