T-SQL Вставить в несколько связанных таблиц, используя условие и не используя курсор - PullRequest
2 голосов
/ 22 декабря 2011

T-SQL Вставить в несколько связанных таблиц, используя условие и без курсора.

Здравствуйте,

У меня есть следующие таблицы

CREATE TABLE [dbo].[TestMergeQuote](
    [uid] [uniqueidentifier] NOT NULL,
    [otherData] [nvarchar](50) NULL,
 CONSTRAINT [PK_TestMergeQuote] PRIMARY KEY CLUSTERED 
(
    [uid] ASC
)WITH (PAD_INDEX  = OFF, STATISTICS_NORECOMPUTE  = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS  = ON, ALLOW_PAGE_LOCKS  = ON) ON [PRIMARY]
) ON [PRIMARY]



ALTER TABLE [dbo].[TestMergeQuote] ADD  CONSTRAINT [DF_TestMergeQuote_uid]  DEFAULT (newid()) FOR [uid]


--=============



CREATE TABLE [dbo].[TestMergeClient](
    [id] [int] IDENTITY(1,1) NOT NULL,
    [otherData] [nvarchar](50) NULL,
 CONSTRAINT [PK_TestMergeClient] 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]

--==============




CREATE TABLE [dbo].[TestMergeDocument](
    [id] [int] NOT NULL,
    [uid_quote] [uniqueidentifier] NOT NULL,
    [id_owner] [int] NOT NULL,
    [id_keeper] [int] NULL,
    [otherData] [nvarchar](50) NULL
) ON [PRIMARY]

GO

ALTER TABLE [dbo].[TestMergeDocument]  WITH CHECK ADD  CONSTRAINT [FK_TestMergeDocument_TestMergeClient_Keeper] FOREIGN KEY([id_keeper])
REFERENCES [dbo].[TestMergeClient] ([id])
GO

ALTER TABLE [dbo].[TestMergeDocument] CHECK CONSTRAINT [FK_TestMergeDocument_TestMergeClient_Keeper]
GO

ALTER TABLE [dbo].[TestMergeDocument]  WITH CHECK ADD  CONSTRAINT [FK_TestMergeDocument_TestMergeClient_Owner] FOREIGN KEY([id_owner])
REFERENCES [dbo].[TestMergeClient] ([id])
GO

ALTER TABLE [dbo].[TestMergeDocument] CHECK CONSTRAINT [FK_TestMergeDocument_TestMergeClient_Owner]
GO

ALTER TABLE [dbo].[TestMergeDocument]  WITH CHECK ADD  CONSTRAINT [FK_TestMergeDocument_TestMergeQuote] FOREIGN KEY([uid_quote])
REFERENCES [dbo].[TestMergeQuote] ([uid])
GO

ALTER TABLE [dbo].[TestMergeDocument] CHECK CONSTRAINT [FK_TestMergeDocument_TestMergeQuote]
GO

И также таблица X с другими различными данными.

Я хочу вставить в эти три таблицы данные, которые уже существуют в этих 3 таблицах, но присвоить им разные идентификаторы, а также заменить некоторые данные в таблице X. Это своего рода «скопировать данные за прошлый год», но добавить новую информацию.

Условием является то, что id_keeper иногда имеет значение null, и для него не нужно делать вставку.

Я знаю, что мне нужно использовать OUTPUT и MERGE, но я не представляю, как добиться чего-то такого сложного.

Код CRUDE для этого с использованием курсора будет:

DECLARE @OldIdDocument INT, @NewIdDocument INT
DECLARE @OldIdOwner INT, @NewIdOwner INT
DECLARE @OldIdKeeper INT, @NewIdKeeper INT
DECLARE @OldIdQuote UNIQUEINDETIFIER, @NewIdQuote UNIQUEINDETIFIER, 


INSERT INTO TestMergeQuote(otherData) 
SELECT TOP(1) otherData FROM TestMergeQuote WHERE uid = @OldIdQuote 
SET @NewIdQuote = @@IDENTITY

INSERT INTO TestMergeClient(otherData) 
SELECT TOP(1) otherData FROM TestMergeClient WHERE uid = @OldIdOwner 
SET @NewIdOwner = @@IDENTITY

IF(@OldIdKeeper  IS NOT NULL)
    BEGIN
        INSERT INTO TestMergeClient(otherData) 
        SELECT TOP(1) otherData FROM TestMergeClient WHERE uid = @OldIdKeeper 
        SET @NewIdKeeper = @@IDENTITY
    END

INSERT INTO TestMergeDocument([uid_quote], [id_owner] , [id_keeper], otherData) 
SELECT TOP(1) @NewIdQuote , @NewIdOwner , @NewIdKeeper  ,otherData FROM TestMergeDocument WHERE uid = @OldIdDocument 
SET @NewIdDocument = @@IDENTITY

1 Ответ

3 голосов
/ 22 декабря 2011

Вам не нужно использовать курсор. То, что я бы попробовал, - это сначала вылить данные в отдельные таблицы, чтобы вы могли манипулировать данными так, как вам хочется.

Сначала как-то так:

select * into TestMergeQuote_Temp from TestMergeQuote

Это создаст новую таблицу с данными, которые вы хотите скопировать. Конечно, вы можете добавить предложение where для фильтрации данных, чтобы не копировать очень большую таблицу.

Затем вы можете добавлять значения, изменять значения, удалять значения в версиях _Temp.

Когда вы будете готовы, вы можете вставить данные обратно. Конечно, вам может потребоваться отключить автоматическую идентификацию, если у вас есть первичный ключ с автоинкрементом. Или, если вам просто нужны новые идентификаторы и вы не хотите создавать идентификаторы вручную, вы сможете просто вставить новые записи и создать для вас новый идентификатор.

Но для начала попробуйте закачать данные в новые таблицы, а затем подумайте о вставке после этого.

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