以下是我要创建的表的DDL。但是,我希望“Expertise_breed”属性派生自“Expertise_animal”。例如,如果'Dog'被输入'Expertise_animal',我不希望能够输入一只猫。我将如何实现这一目标? 我正在使用SQL Server Management Studio 2012
CREATE TABLE tExpertise
(
Expertise_ID int NOT NULL PRIMARY KEY, --E.G Data '001'
Expertise_type varchar(8) NOT NULL, --E.G Data 'Domestic'
Expertise_animal varchar(30) NOT NULL, --E.G Data 'Dog'
Expertise_breed varchar(30) NOT NULL --E.G Data 'Poodle'
)
答案 0 :(得分:2)
这是一种关系数据情况,你应该使用关系表。
我会有三个 AnimalClassification - (国内,野外,其他) 动物种(狗,猫,山羊) AnimalBreed(贵宾犬,比格犬) 动物物种将具有动物分类的外键,即 狗 - 国内 动物品种将拥有动物物种的外键,即 比格犬 - 狗
答案 1 :(得分:-1)
您可以在插入和/或更新时创建触发器,并比较每行的这两列。您可以通过'插入'来参考插入的条目。别名。
如果您知道允许的映射(例如dog x poodle),您可以将其存储在某个表中并在插入中连接到它以过滤掉错误的映射。
答案 2 :(得分:-1)
理论上,你可以使用表级constraints来实现你想要的东西,这是一种通用的方法(未经过测试):
CREATE FUNCTION dbo.validateExpertise(
@expertise_type varchar(8),
@Expertise_animal varchar(30),
@Expertise_breed varchar(30)
)
RETURNS BIT
AS
BEGIN
IF (@Expertise_animal == 'dog' AND @Expertise_breed != 'dog')
RETURN 0;
-- other validations can come here
RETURN 1;
END
GO
-- add a table level constraint
-- WITH NOCHECK can be used to not check existing data
ALTER TABLE detailTable ADD CONSTRAINT chkExpertise
CHECK (dbo.validateExpertise(expertise_type, Expertise_animal, Expertise_breed) = 1)
虽然这可能对您有所帮助,但不建议在数据库级别进行此类复杂验证。复杂的验证意味着(至少)在应用程序的业务层中实现,通常在Logic tier内(通常是ASP.NET MVC,WCF服务,Web服务等)(也有一些验证)在表示层,以避免往返时间延迟。
数据库主要用于数据持久性和提取。当然,欢迎使用FK
s,unique
约束,列级约束等简单约束,因为它们可以作为一个良好的安全网。
另外,请记住,上面提到的约束会触发表中的每个INSERT
或UPDATE
,并且可能严重降低涉及大量记录的查询的性能。