合并投掷外键冲突

时间:2013-11-06 17:49:28

标签: sql sql-server

这是我的SQL语句的一部分:

MERGE INTO Scyk.dbo.Threads AS d
USING (SELECT Id,Question,QuestionTitle, Answer, Category FROM Homework.dbo.Zadanes) AS s
ON 1 = 2 
   WHEN NOT MATCHED THEN
      INSERT (CurrentValue, NumberOfPosts, TotalValue, Views, Title, DateCreated, LastPostAuthor, LastPostDateTime, IsDeleted, Restricted, RestrictWrite, Sticked, CategoryName, AuthorUserName)
      VALUES (0, 2, 0, 0, s.QuestionTitle, CURRENT_TIMESTAMP, 'zadania', DATEADD(second, 1, CURRENT_TIMESTAMP), 0, 0, 0, 0, s.Category, 'zadania')

这是我得到的错误:

  

MERGE语句与FOREIGN KEY约束“FK_dbo.Threads_dbo.Categories_CategoryName”冲突。冲突发生在数据库“Scyk”,表“dbo.Categories”,列“名称”。

所以我做的第一件事就是我检查了外键的完整性:

SELECT Distinct(Category) FROM [Homework].[dbo].[Zadanes]
where not exists
(select distinct(Name) from Scyk.dbo.Categories)

但这没有任何回报,这意味着外键很好。那么这里发生了什么?

2 个答案:

答案 0 :(得分:5)

发生的事情是您的查询显示

Homework.dbo.Zadanes中选择任何类别,但前提是Scyk.dbo.Categories中没有行。

据推测,后一个表中有行,因此您的查询没有返回任何内容。

尝试

SELECT z.Category 
  FROM [Homework].[dbo].[Zadanes] z LEFT OUTER JOIN
       [Scyk].[dbo].[Categories] c
    ON z.Category = c.Name
 WHERE c.Name IS NULL
 GROUP BY z.Category

此外,除非您使用OUTPUT子句一次重新映射一堆ID,否则没有理由使用MERGE代替INSERT

答案 1 :(得分:5)

您应该停止使用MERGE,恕我直言,并使用普通INSERTMERGE在这里买什么?

在某些或所有受支持的SQL Server版本中,至少有15个错误未被修复:

http://www.mssqltips.com/sqlservertip/3074/use-caution-with-sql-servers-merge-statement/

它听起来像this is the one causing your issue,并且已经关闭,因为无法修复。 last one may resolve your issueget the fix from KB #956718),但不知怎的,我对此表示怀疑。即使它确实如此,那么您可能会受到那里列出的其他14个(或者尚未发现的其中一个)的影响。遗憾的是,这是一个用最少的测试发布一个半完成的功能然后忽略3个版本的情况。

如果要检查外键,查询应该如下所示:

SELECT Distinct(Category) FROM [Homework].[dbo].[Zadanes] AS z
where not exists
(select 1 from Scyk.dbo.Categories AS c WHERE c.name = z.Category);

虽然奇怪的是你在名字上有一个外键而不是一个CategoryID。当名称改变时会发生什么?你有级联选项吗?在'Electronics'的每一行中重复Zadanes个或更长的类别名称,您浪费了多少空间?