SQL Server 不支持创建此类约束。
但是您可以通过编程方式模拟链接而没有太多麻烦。
CREATE TABLE tbl_Event
(
[idEvent] INT IDENTITY(1,1) NOT NULL,
[TableSource] INT NOT NULL,
[SourceId] INT NOT NULL
--Events fields
CONSTRAINT [PK_Tests] PRIMARY KEY CLUSTERED
(
[id] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
在上面的例子中,SourceId 是外键
TableSource 用于知道外键来自哪个表。
在表源中,您可以使用表的 sys.objects.object_id。
但是,由于您对那些由 SQL 管理的键没有太多控制权,因此我建议您使用自己的表,并为每个表定义常量而不是 sys.objects。
通过这种方式,您还可以更好地控制该表中哪个表可以有外键,并且它变得非常方便加班。
CREATE TABLE tbl_tableSource(
[idTableSource] INT IDENTITY(1,1) NOT NULL,
[Constant] INT NOT NULL,
[Name] NVARCHAR(255) NULL
CONSTRAINT [PK_Tests] PRIMARY KEY CLUSTERED
(
[idTableSource] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]
INSERT INTO tbl_tableSource
VALUES(1000, 'tbl_SomeTable')
INSERT INTO tbl_tableSource
VALUES(2000, 'tbl_SomeOtherTable')
此外,这种关系在性能方面不如标准关系好。因此,您的键和常量的字段类型非常重要。它不应该很重。这是因为您需要在 tbl_event 上创建一个索引。
要模拟级联删除ON,你需要像这样在父表上实现触发器:
CREATE TRIGGER OneParentTableOnDelete ON tbl_SomeTable
FOR DELETE
AS
BEGIN
DELETE tbl_Event
FROM DELETED
INNER JOIN tbl_Event ON tbl_Event.TableSource = [Constant for tbl_SomeTable]
AND tbl_Event.idSource = DELETED.id --PrimaryKey
END
要检索数据,您可以这样做
--For events about one foreign key
SELECT *
FROM tbl_event
WHERE tbl_Event.TableSource = [Constant for tbl_SomeTable]
AND tbl_Event.idSource = @idPrimareyKeyOfSomeTable
--Fore events about multiple foreign key
SELECT *
FROM [tbl_SomeTable]
INNER JOIN tbl_event ON tbl_Event.TableSource = [Constant for tbl_SomeTable]
AND tbl_Event.idSource = [tbl_SomeTable].id --PrimaryKey