假设我们有三个表的客户,市和国家保持在SQL Server中的循环引用数据完整性2012
的国家表:
- ID(PK)
- 名称。
City表:
- ID(PK)
- CountryID(FK)
- 名称
Customer表:
- ID(PK ) 个
- CountryID(FK)(NULL)
- CityID(FK)(NULL)
- 名称 等...
正如你可以猜测用户可能会或可能不会分配CityID或CountryID。
那么确保在插入/更新客户时最好的方法是什么,我们最终不会得到一个不在指定国家的城市?
假设我们有三个表的客户,市和国家保持在SQL Server中的循环引用数据完整性2012
的国家表:
City表:
Customer表:
正如你可以猜测用户可能会或可能不会分配CityID或CountryID。
那么确保在插入/更新客户时最好的方法是什么,我们最终不会得到一个不在指定国家的城市?
我不知道那将是最好的方式,但你可以添加一个功能,并用它在你的检查约束:
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
这是个好主意:)但是你错过了CheckCityInCountry的CountryID参数。我们并不试图确定一个城市是否存在,我们想要的是检查客户是否已分配国家,以及稍后是否有人向该客户分配城市以确保城市的国家/地区ID与客户的国家/地区ID匹配。感谢您的建议。 – 2013-03-09 12:49:10
@mihailshishkov Thnx,我已经更新了代码... – Mortalus 2013-03-09 12:54:25
我会非常非常小心地在检查约束中使用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
设置了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)
只要国家只需要id城市不知道,清除CountryID分配CityID。查询将是国家的IsNull(CountryFromCityLookUp,CountryLookup)。 – bummi 2013-03-09 12:25:50
什么是CHECK约束或TRIGGER的适当语法?谢谢。 – 2013-03-09 12:28:12