我的网站master
的制作detail
上有table
和SQL Server database
hoster
。我的REST
服务的Android apps
服务每天都会执行许多插入操作。这些服务会对master
进行插入,然后对detail table.
进行多次插入。这一切都在99.999%
的时间内完成,但每次我都开始得到这个:
INSERT语句与FOREIGN KEY约束冲突 " FK_TTLegs_TTMaster&#34 ;.冲突发生在数据库中 " SQL2008R2_797967_golfstats",table" dbo.TTMaster",column ' EMAILADDRESS&#39 ;.该语句已终止。 key = 12703032675:再试一次
现在我意识到这句话说我在insert
表中没有detail
记录时正在master
。但是还有。
这个问题每年发生四到五次,我从来没有弄清楚导致它的原因。数据库是SQL Server 2014
。 emailaddress
为nvarchar 50
。
答案 0 :(得分:1)
由于这种情况很少发生,因此一个选项是禁用此外键并使用SQL作业进行检查,该作业可以在日志表中运行未通过此验证的记录。像这样:
SELECT D.*
FROm dbo.FK_TTLegs_TTMaster D
WHERE NOT EXISTS (SELECT 1 FROM dbo.TTMaster M ON M.emailadrress = D.emailadrress)
因此,您临时允许无效数据,但您可以找到违反约束的确切记录。
作业可以按照您认为合适的频率运行,并在发生错误时通知您(电子邮件等)。
注意:使用VARCHAR
作为FK
s不是一个好主意,因为比较可能会导致麻烦(取决于整理,前导或尾随空白),它是不是性能方面(详细信息表中的每个INSERT或UPDATE必须根据主表验证数据,并且字符串比较比整数比较更昂贵)。
<强> [编辑] 强>
以上文字可能对调查有用,但我认为真正的问题是桌面设计。如果主服务器和详细信息上的电子邮件地址应该相同,那么它应该只存储在主表中。
从emailaddress
dbo.TTLegs_TTMaster
使用surrogate key
链接主表和详细信息表,如果在master
上无法使用自然表
如果INSERT
是从应用层(.NET
,Java
等)完成的,它可以在INSERT
<之前对主表进行验证/ p>
如果在INSERT
(导入,SQL Server
等)中完成ETL
,则只能执行那些具有匹配电子邮件地址并报告的插入内容错误记录那些未通过此验证的记录