考虑以下设计:
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'.
有没有办法在不涉及游标的情况下正确复制数据?
答案 0 :(得分:2)
感谢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;
然后我可以使用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)
答案 1 :(得分:0)
我知道您希望严格使用TSQL执行此操作,但是,从表格体验来看,我发现将OldProductId
字段添加到Product
表并从中映射产品部件最简单:< / p>
INSERT INTO Product (ProductName, OldProductId)
SELECT ProductName, ProductId
FROM Product
WHERE CompanyId = @companyId