2013-03-09 71 views
1

假设我们有三个表的客户,市和国家保持在SQL Server中的循环引用数据完整性2012

的国家表:

  • ID(PK)
  • 名称。

City表:

  • ID(PK)
  • CountryID(FK)
  • 名称

Customer表:

  • ID(PK )
  • CountryID(FK)(NULL)
  • CityID(FK)(NULL)
  • 名称 等...

正如你可以猜测用户可能会或可能不会分配CityID或CountryID。

那么确保在插入/更新客户时最好的方法是什么,我们最终不会得到一个不在指定国家的城市?

+0

只要国家只需要id城市不知道,清除CountryID分配CityID。查询将是国家的IsNull(CountryFromCityLookUp,CountryLookup)。 – bummi 2013-03-09 12:25:50

+0

什么是CHECK约束或TRIGGER的适当语法?谢谢。 – 2013-03-09 12:28:12

回答

1

我不知道那将是最好的方式,但你可以添加一个功能,并用它在你的检查约束:

CREATE FUNCTION CheckCityInCountry(@CityID int, @CountryID int) 
RETURNS int 
AS 
BEGIN 
    DECLARE @retval int 
    SELECT @retval = COUNT(*) 
    FROM Cityies CI inner join Countries CO on (CI.CountryID, CO.ID) 
    WHERE CO.CountryID = @CountryID and CityID = @CityID 
    RETURN @retval 
END; 
GO 

该函数将返回1,如果这个城市是一个国家和0除此以外。

然后使用该函数添加一个检查约束:

ALTER TABLE Customers 
ADD CONSTRAINT chk_CheckCityInCountry CHECK (
    CityID is null OR 
    dbo.CheckCityInCountry(CityID,CountryID) >= 1 
); 
GO 
+0

这是个好主意:)但是你错过了CheckCityInCountry的CountryID参数。我们并不试图确定一个城市是否存在,我们想要的是检查客户是否已分配国家,以及稍后是否有人向该客户分配城市以确保城市的国家/地区ID与客户的国家/地区ID匹配。感谢您的建议。 – 2013-03-09 12:49:10

+0

@mihailshishkov Thnx,我已经更新了代码... – Mortalus 2013-03-09 12:54:25

+1

我会非常非常小心地在检查约束中使用UDF。请参阅http://connect.microsoft.com/SQLServer/feedback/details/301828(已关闭,因为无法修复),http://sqlblog.com/blogs/alexander_kuznetsov/archive/2009/06/25/scalar-udfs包裹检查约束条件非常慢并且可能会失败,因为multirow-updates.aspx和http://sqlblog.com/blogs/tibor_karaszi/archive/2009/12/17/be -careful-with-constraints-calling-udfs.aspx – 2013-03-09 13:42:40

0

设置了FK关系到两个国家和城市的表

改变城市表有CountryID,CityID的复合PK。
FK关系必须同时参考两者。

FK未在null上执行。

一个警告是你可以输入一个空的国家坏的城市ID,因为在这一点上既没有强制执行FK。
但我认为这可以用CHECK CONSTRAINT强制执行。

ALTER TABLE dbo.CustomerCountyCity ADD CONSTRAINT CK_CustomerCountyCity 
    CHECK (CountryID is not null OR CityID is Null)