我有一个表,其主键也是另一个表的主键的外键(即在数据库中模拟的“继承”)。
/****** Object: Table [dbo].[BaseClass] Script Date: 07/15/2011 18:17:27 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[BaseClass](
[ID] [int] IDENTITY(1,1) NOT NULL,
[Title] [nvarchar](50) NOT NULL,
[Description] [nvarchar](max) NOT NULL,
CONSTRAINT [PK_BaseClass] 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]
GO
USE [TestConcepts]
GO
/****** Object: Table [dbo].[DerivedTable] Script Date: 07/15/2011 18:17:49 ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[DerivedTable](
[ID] [int] IDENTITY(1,1) NOT NULL,
[SpecialProperty] [uniqueidentifier] NOT NULL,
CONSTRAINT [PK_DerivedTable] 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]
GO
ALTER TABLE [dbo].[DerivedTable] WITH CHECK ADD CONSTRAINT [FK_DerivedTable_BaseClass] FOREIGN KEY([ID])
REFERENCES [dbo].[BaseClass] ([ID])
GO
ALTER TABLE [dbo].[DerivedTable] CHECK CONSTRAINT [FK_DerivedTable_BaseClass]
GO
在这种情况下插入记录的正确方法是什么?显然插入不会返回插入行的PK(加上子表的PK也是标识符)。
答案 0 :(得分:4)
以下是此模式的 few examples 。
子类型表应不具有自动递增ID,ID与超类型表中的ID匹配。
基本技术(使用您的示例)看起来像
DECLARE @MY_ID integer;
INSERT INTO BaseTable(Title, Description)
VALUES ('title_here', 'blah, blah');
SELECT @MY_ID = SCOPE_IDENTITY();
INSERT INTO DerivedTable(ID, SpecialProperty)
VALUES (@MY_ID, newid()); -- the SpecialProperty is uniqueidentifier
一种方法是创建一个视图,一个用于每个子类型表,或者只有一个用于所有子类型表。然后在视图上创建INSTEAD OF INSERT TRIGGER
并使用触发器内的技术。
您也可以找到 this technique 来捕获多个有用的插入ID。
答案 1 :(得分:0)
没有人称之为“继承”。那不是它的本质。这是一种关系,即RDBMS中的R.
INSERT do 告诉您刚刚插入的行的PK。在SQL Server上查看@@ SCOPE_IDENTITY。
答案 2 :(得分:0)
DERIVEDCLASS表可能具有自动递增(标识)PK但如果是这样,则必须有另一列作为外键引用返回BASETABLE:
BASETABLE
id int pk autoincrement
baseattribute1
baseattribute2
etc etc
DERIVEDTABLE
id int pk autoincrement
**baseid** foreign key references BASETABLE(id)
extendedattribute1
extendedattribute2
这将允许每个基本实体的多个派生。如果需要,可以在DERIVEDTABLE.baseid上放置一个唯一索引或将baseid设为PK,这样可以防止这种情况发生。
以下将实例化基类的成员及其派生实例和/或扩展属性(如果有的话)将取决于baseid在DerivedTable中是否具有唯一约束;如果后者可能是与BaseTable一对一关系的PK,而不是多对一]:
select * from BASETABLE
LEFT JOIN DERIVEDTABLE
on BASETABLE.id = DERIVEDTABLE.baseid
未扩展的基类实例在extendedattribute列中将为NULL。
要仅查找已扩展的实体,请使用内部联接:
select * from DERIVEDTABLE
inner join BASETABLE
on DERIVEDTABLE.baseid = BASETABLE.id