[英]UNIQUE CONSTRAINT on a column from foreign table in SQL Server 2008
我有兩個表:
create table [dbo].[Main]
(
[ID] [int] identity(1,1) primary key not null,
[No] [int] not null,
[Sign] [char](1) not null
)
create table [dbo].[Names]
(
[ID_Main][int] primary key not null,
[Name][nvarchar](128) not null,
constraint [FK_Main_Users] foreign key ([ID_Main]) references [dbo].[Main]([ID]),
constraint [CK_Name] unique ([Name], [Sign])
)
問題出在第二個約束CK_Name
有沒有一種方法可以從外部表中創建約束目標列?
編輯:
說明。 我在使用EntityFramework的Silverlight應用程序中使用這些表。 每個類型繼承都由Table創建實體,因此代碼如下所示:
public abstract class Main
{
// main properties
}
public class Names : Main
{
// names properties
}
這迫使我不要使用sql視圖。
樣本數據。
--------------------------------------------- | Main | Names | --------------------------------------------- | ID | Sign | No | ID_Main | Name | --------------------------------------------- | 1 | A | 1 | 1 | 'qwe' | | 2 | B | 1 | 2 | 'qwe' | | 3 | B | 1 | 3 | 'qwe' | | 4 | C | 1 | 4 | 'qwe' | | 5 | A | 2 | 5 | 'asd' | | 6 | B | 2 | 6 | 'asd' | | 7 | B | 2 | 7 | 'asd' | | 8 | C | 2 | 8 | 'asd' |
如您所見,有些行具有相同的名稱,但具有不同的符號。 不能有帶有相同符號的任何非唯一名稱。
我要強制說,只有一個名稱帶有Sign = A的名稱,只有一個名稱帶有Sign C的名稱,但有許多帶有Sign = B的名稱
是的,您可以使用索引視圖並在過濾后的結果集的(符號,名稱)上創建唯一約束(索引),從而實施此類約束。
CREATE VIEW dbo.vwSelectiveUniqueSignName WITH SCHEMABINDING
AS
SELECT [Sign], Name
FROM
dbo.Main INNER JOIN dbo.Names on ID = ID_Main
WHERE
dbo.Main.Sign IN ('A', 'C')
GO
CREATE UNIQUE CLUSTERED INDEX IDX_vwSelectiveUniqueSignName_Unique_Sign_Name
ON dbo.vwSelectiveUniqueSignName ( [Sign] ASC, Name ASC )
GO
測試:
-- using your sample data:
/* Case 1 Sign = 'A', Name = 'qwe': this will throw error 'cannot insert duplicate key row in object ... with unique index ... */
BEGIN TRAN NotAllowedMoreThan_1
insert dbo.Main ([Sign]) OUTPUT inserted.* values ('A') /* same for 'C' */
insert dbo.Names (ID_Main, Name) OUTPUT inserted.* SELECT SCOPE_IDENTITY(),'qwe'
COMMIT TRAN NotAllowedMoreThan_1
GO
/* Case 2 Sign = 'B', Name = 'qwe': this will pass > 1 times (note GO loop) */
BEGIN TRAN AllowedMoreThan_1
insert dbo.Main ([Sign]) OUTPUT inserted.* values ('B') /* any other than A, C */
insert dbo.Names (ID_Main, Name) OUTPUT inserted.* SELECT SCOPE_IDENTITY(),'qwe'
COMMIT TRAN AllowedMoreThan_1
GO 2
要回答您的問題,沒有辦法在檢查約束(或與此相關的任何其他類型的約束)中引用外部表中的列。 但是,根據您的情況,您要確保Names.Name
和Main.Sign
任何組合都是唯一的。 為此,您只需在兩列的每一列上添加唯一約束即可:
Alter Table dbo.Main Add Constraint UC_Main Unique Nonclustered ( Sign )
GO
Alter Table dbo.Names Add Constraint UC_Names Unique Nonclustered ( Name )
不需要一起在ID_Main和Name上創建唯一約束,因為已經需要ID_Main通過其主鍵約束來唯一。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.