我正在对没有外键约束的数据库程序运行维护,即使它确实应该......
Logging表有一个ParentID列和一个ParentType列。 ParentType列中的条目确定ParentID引用的表。
我正在寻找的是关于添加这种依赖于输入的外键约束的最佳方法的想法...憎恶......
我很想能够抛出这个程序的整个后端并重新开始,但是如果没有我打破一切那么它已经不可靠了。在这一点上收紧后端似乎是我最好的。唯一真正的替代方案似乎是抛弃整个计划。
那么,是的,关于在SQL方面限制此列中数据的最佳方法的想法?
编辑:我已经可以说清楚了......是的,所以我有Logging表,然后是TableOne和TableTwo。如果输入到Logging的行尝试在ParentType列中添加一行1,那么ParentID必须出现在TableOne中,如果ParentType为2,则ParentID必须出现在TableTwo中。
答案 0 :(得分:1)
您最好的选择可能是在Logging表上将此规则实现为INSTEAD OF触发器,您可以根据相应的表检查ID,如果发生FK违规则拒绝INSERT / UPDATE。粗略的伪代码,如:
CREATE TRIGGER tr_io_iu_Logging ON Logging
INSTEAD OF INSERT, UPDATE
AS
BEGIN
IF UPDATE(ParentID) BEGIN
IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableOne t1 ON i.ParentID = t1.ID WHERE i.ParentType=1 AND t1.ID IS NULL)
/* perform the insert */
ELSE
/* raise error */
IF NOT EXISTS(SELECT 1 FROM Inserted i LEFT JOIN TableTwo t2 ON i.ParentID = t2.ID WHERE i.ParentType=2 AND t2.ID IS NULL)
/* perform the insert */
ELSE
/* raise error */
END /* IF */
END /* trigger */
答案 1 :(得分:1)
假设您是通过SP输入数据,我会考虑使用带有参数的UDF和值类型,该类型执行查找以对照表格类型中的相应表进行验证。这在性能方面不会是一个尖叫者,但是你可以在插入之前将调用放入插入SP中进行验证,并且你将能够在UDF中集中验证。
答案 2 :(得分:1)
创建两个持久计算列,如下所示:
CarID AS (CASE WHEN Type='Car' THEN ParentID END)
TruckID AS (CASE WHEN Type='Truck' THEN ParentID END)
并让FK将它们引用到您的表格中。