Tsql 具有标识列的重复记录

Tsql 具有标识列的重复记录,tsql,Tsql,考虑以下设计: 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 (

考虑以下设计:

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'.

是否有任何方法可以在不涉及游标的情况下正确复制数据?

我知道您希望严格使用TSQL执行此操作,但是,根据经验,我发现将
OldProductId
字段添加到
产品
表并从中映射产品零件最简单:

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

多亏了Mikael,我发现我实际上可以使用
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;
然后我可以使用
@productRemap
中的映射插入
ProductPart

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)

不幸的是,我无法向
产品
表中添加任何其他列。如果您使用SQL Server 2008,则可以使用
合并
。看看这个问题。