我在SSMS中遇到一个奇怪的问题。改变表添加约束与改变表添加检查约束
我的表设计大量使用组合键来在所有传递关系中执行严格而健壮的参照完整性 - 代价是违反了BCNF,但实际上它证明非常方便,尤其是对于实体框架的自动导航属性(相关对于我之前发布的这个问题:How can I enforce second-degree relationships without composite keys?)。
无论如何,我遇到了使用SSMS 2014图编辑器添加外键关系的问题。
这里是我的问题的一个简单的例子:
CREATE TABLE Tenants (
TenantId bigint IDENTITY(1,1) PRIMARY KEY
)
CREATE TABLE Shops (
TenantId bigint, -- Is a FOREIGN KEY(Tenants REFERENCES TenantId)
ShopId bigint IDENTITY(1,1)
PRIMARY KEY(TenantId, ShopId)
)
CREATE TABLE Job (
TenantId bigint, -- Is a FOREIGN KEY(Tenants REFERENCES TenantId)
ShopId bigint, -- Is a FOREIGN KEY(Shops REFERENCES TenantId)
JobId bigint IDENTITY(1,1)
PRIMARY KEY(TenantId, ShopId, JobId)
)
我有这样的列很多的表,并使用图表编辑器来创建具有参照完整性复合键的关系正常工作(你只需按Ctrl +点击每个复合FK列,然后用一些时间拖动到主键表中,然后单击确定,这就是它。
然而,它失败。例如,如果我选择在Jobs
TenantId
和ShopId
并拖动到Shops
表,它给了我这个e RROR:
The columns in table 'Shops' do not match an existing primary key or UNIQUE constraint.
...尽管这两列是的Shops
表的主键!
我SSMS生成因为它是试图添加约束的SQL,它给了我这个(格式化矿,另外TRANSACTION
代码中删除):
ALTER TABLE
dbo.Jobs
ADD CONSTRAINT
FK_Jobs_Shops
FOREIGN KEY
(ShopId, TenantId) REFERENCES dbo.Shops (ShopId, TenantId)
ON UPDATE
NO ACTION
ON DELETE
NO ACTION
当我直接运行它时,SQL Server给了我这个错误:
Msg 1776, Level 16, State 0, Line 1 There are no primary or candidate keys in the referenced table '
dbo.Shops
' that match the referencing column list in the foreign key 'FK_Jobs_Shops
'.Msg 1750, Level 16, State 0, Line 1 Could not create constraint or index. See previous errors.
注意其他表已有的Shops
表定义的外键关系 - 所以我不知道发生了什么事情。所以我告诉SSMS到脚本来创建看似工作的制约 - 然后我改名的事情,使之创造我本来想(Jobs
和Shops
之间)的约束,它给了我这个不同输出(格式化矿):
ALTER TABLE
[dbo].Jobs WITH CHECK
ADD CONSTRAINT
[FK_Jobs_Shops]
FOREIGN KEY
([TenantId], [ShopId]) REFERENCES [dbo].[Shops] ([TenantId], [ShopId])
GO
ALTER TABLE
[dbo].[Jobs]
CHECK CONSTRAINT
[FK_Jobs_Shops]
GO
当我跑这个它的工作!
注意区别:
- 添加的
WITH CHECK
- 缺乏
ON UPDATE
/ON DELETE
报表 - 约束在两个语句,而不是一个影响。
我的问题:
- 我有没有发现在SQL Server中的错误?
- 两个约束定义语法之间是否存在语义差异?
- 或者说,为什么一个人工作,而不是另一个?
你可以看到http://stackoverflow.com/questions/529941/with-check-add-constraint-followed-by-check-constraint-vs-add-constraint,也许有用 – Kiquenet