我在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