Повторяющиеся записи с идентификатором столбца - PullRequest
0 голосов
/ 04 июля 2011

Рассмотрим следующий дизайн:

Company TABLE (
    CompanyId int NOT NULL IDENTITY PRIMARY KEY,
    CompanyName nvarchar(max))
Product TABLE (
    ProductId int NOT NULL IDENTITY PRIMARY KEY,
    CompanyId int NOT NULL,
    ProductName nvarchar(max))
ProductPart TABLE (
    ProductPartId int NOT NULL IDENTITY PRIMARY KEY,
    ProductId int NOT NULL,
    ProductPartName)

Мне нужно продублировать данные компании (с CompanyId == @companyId), чтобы они содержали точно такие же данные.

Первый шаг очевиден:

INSERT INTO Company(CompanyName)
SELECT @newCompanyName
FROM Company
WHERE CompanyId = @companyId

DECLARE @newCompanyId = SCOPE_IDENTITY()

Без таблицы ProductPart было бы тривиально скопировать и данные Product:

INSERT INTO Product (ProductName)
SELECT ProductName
FROM Product
WHERE CompanyId = @companyId

Но для правильного дублирования данных ProductPart мне нужноиметь данные о сопоставлении продуктов между старыми и новыми компаниями.

Я пытался использовать предложение OUTPUT, но, к сожалению, оно не поддерживает мой сценарий:

DECLARE @productRemap TABLE (OldProductId int NOT NULL, NewProductId int NOT NULL PRIMARY KEY)
INSERT INTO Product (ProductName)
    OUTPUT ProductId, inserted.ProductId
        INTO @productRemap
SELECT ProductName
FROM Product
WHERE CompanyId = @companyId
-- Invalid column name 'ProductId'.

Есть ли способ скопироватьданные правильно без использования курсоров?

Ответы [ 2 ]

2 голосов
/ 04 июля 2011

Благодаря Микаэлю я обнаружил, что на самом деле могу использовать MERGE вместо INSERT:

DECLARE @productRemap
    TABLE (OldProductId int NOT NULL, NewProductId int NOT NULL)

-- Duplicate products
MERGE INTO Product AS t
USING (
    SELECT *
    FROM Product
    WHERE CompanyId = @companyId) AS s
ON (0 = 1)
WHEN NOT MATCHED THEN
    INSERT (ProductName, CompanyId)
    VALUES (ProductName, @newCompanyId)
    OUTPUT s.ProductId, inserted.ProductId
        INTO @productRemap;

Затем я могу вставить в ProductPart, используя отображение из @productRemap:

MERGE INTO ProductPart AS t
USING (
    SELECT * FROM ProductPart
        INNER JOIN @productRemap ON ProductId = OldProductId) AS s
ON (0 = 1)
WHEN NOT MATCHED THEN
    INSERT (ProductId, ProductPartName)
    VALUES (NewProductId, ProductPartName)
0 голосов
/ 04 июля 2011

Я понимаю, что вы собираетесь делать это строго с TSQL, однако, по опыту работы с формами, я нашел, что проще всего добавить поле OldProductId в таблицу Product и сопоставить детали продукта с этой строки:*

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