Вставка записей в таблицы базы данных с использованием «наследования» - PullRequest
1 голос
/ 16 июля 2011

У меня есть таблица, первичный ключ которой также является внешним ключом первичного ключа другой таблицы (т. Е. «Наследование», как моделируется в базе данных).

/****** 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 таблицы ребенка также является тождественным).

Ответы [ 3 ]

4 голосов
/ 16 июля 2011

Вот несколько примеров этого шаблона.

Таблица подтипов должна не иметь идентификатор автоинкремента,Идентификатор совпадает с идентификатором в таблице супертипов.

Базовый метод (на вашем примере) выглядит примерно так:

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 в представлении и используйте технику внутри триггера.

Вы также можете найти эту технику для захвата нескольких вставленных идентификаторов.

0 голосов
/ 16 июля 2011

Таблица 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; если последнее, то это может быть PK в отношениях один-к-одному с BaseTable, а не многие-к-одному]:

          select * from BASETABLE
          LEFT JOIN DERIVEDTABLE
          on BASETABLE.id = DERIVEDTABLE.baseid

Экземпляры базового класса, которые не были расширены, будут иметь значение NULL в столбцах расширенных атрибутов.

Чтобы найти только те сущности, которые были расширены, используйте внутреннее соединение:

         select * from DERIVEDTABLE
         inner join BASETABLE
         on DERIVEDTABLE.baseid = BASETABLE.id
0 голосов
/ 16 июля 2011
  1. Никто не называет это "наследством".Это не то, что есть.Это отношение, R в СУБД.

  2. INSERT do сообщают вам PK только что вставленной строкиПосмотрите на @@ SCOPE_IDENTITY на SQL Server.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...