使用外键插入数据
Insert Data with Foreign Keys
我有两个 table 与外键约束相连。每个 table 都有一个主键(ProductID,BaseProductID),它是一个自动递增的标识列。
每个 BaseProduct 在导入过程中只有 1 个 Product。
BaseProduct
- BaseProductID
- BaseProductName
Product
- ProductID
- BaseProductID
- ProductName
我尝试从具有相同表但不同种子值的不同数据库向两个 table 中插入行。我不想保留源数据库中的 ID。
有没有办法在一条语句中做到这一点?
编辑
Select 会是
Select ProductName FROM @SourceProduct
WHERE Not ProductName in (
select ProductName FROM @TargetBaseProduct
)
我尝试了 Giorgi 的解决方案,它很接近,但是
的匹配
tgt.BaseProductID = src.BaseProductID
如果目标已经有 BaseProductID = 1 的条目,则导致不插入 BaseProductID = 1 的源行的结果。
DECLARE @SourceBaseProduct TABLE
(
BaseProductID INT ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @SourceProduct TABLE
(
ProductID INT ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
DECLARE @TargetBaseProduct TABLE
(
BaseProductID INT IDENTITY(1, 1) ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @TargetProduct TABLE
(
ProductID INT IDENTITY(1, 1) ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
INSERT INTO @SourceBaseProduct
VALUES ( 1, 'BaseProduct1' ),
( 2, 'BaseProduct2' ),
( 4, 'BaseProduct3' )
INSERT INTO @SourceProduct
VALUES ( 3, 1, 'Product1' ),
( 9, 2, 'Product2' ),
( 27, 4, 'Product3' )
INSERT INTO @TargetBaseProduct
(
BaseProductName
)
VALUES ( 'Existing Product Base' )
INSERT INTO @TargetProduct(
BaseProductID ,
ProductName)
VALUES ( @@IDENTITY, 'Existing Product' )
MERGE INTO @TargetBaseProduct tgt
USING
( SELECT sbp.BaseProductID ,
sbp.BaseProductName ,
sp.ProductName
FROM @SourceBaseProduct sbp
JOIN @SourceProduct sp ON sp.BaseProductID = sbp.BaseProductID
) AS src
ON tgt.BaseProductID = src.BaseProductID
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES ( src.BaseProductName )
OUTPUT
Inserted.BaseProductID ,
src.ProductName
INTO @TargetProduct(BaseProductID, ProductName);
SELECT * FROM @TargetBaseProduct
SELECT * FROM @TargetProduct
输出
BaseProductID BaseProductName
1 Existing Product Base
2 BaseProduct2
3 BaseProduct3
ProductID BaseProductID ProductName
1 1 Existing Product
2 2 Product2
3 3 Product3
预期结果
BaseProductID BaseProductName
1 Existing Product Base
2 BaseProduct1
3 BaseProduct2
4 BaseProduct3
ProductID BaseProductID ProductName
1 1 Existing Product
2 2 Product1
3 3 Product2
4 4 Product3
编辑
使用
ON 1 = 0
按照 Giorgi 的建议给出了正确的结果
如果我没猜错,MERGE
:
DECLARE @SourceBaseProduct TABLE
(
BaseProductID INT ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @SourceProduct TABLE
(
ProductID INT ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
DECLARE @TargetBaseProduct TABLE
(
BaseProductID INT IDENTITY(1, 1) ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @TargetProduct TABLE
(
ProductID INT IDENTITY(1, 1) ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
INSERT INTO @SourceBaseProduct
VALUES ( 1, 'BaseProduct1' ),
( 2, 'BaseProduct2' ),
( 4, 'BaseProduct3' )
INSERT INTO @SourceProduct
VALUES ( 3, 1, 'Product1' ),
( 9, 2, 'Product2' ),
( 27, 4, 'Product3' )
MERGE INTO @TargetBaseProduct tgt
USING
( SELECT sbp.BaseProductID ,
sbp.BaseProductName ,
sp.ProductName
FROM @SourceBaseProduct sbp
JOIN @SourceProduct sp ON sp.BaseProductID = sbp.BaseProductID
) AS src
ON tgt.BaseProductID = src.BaseProductID
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES ( src.BaseProductName )
OUTPUT
Inserted.BaseProductID ,
src.ProductName
INTO @TargetProduct(BaseProductID, ProductName);
SELECT * FROM @TargetBaseProduct
SELECT * FROM @TargetProduct
输出:
BaseProductID BaseProductName
1 BaseProduct1
2 BaseProduct2
3 BaseProduct3
ProductID BaseProductID ProductName
1 1 Product1
2 2 Product2
3 3 Product3
编辑:如果您也想插入现有行,则更改
ON tgt.BaseProductID = src.BaseProductID
到
ON 1 = 0
我有两个 table 与外键约束相连。每个 table 都有一个主键(ProductID,BaseProductID),它是一个自动递增的标识列。 每个 BaseProduct 在导入过程中只有 1 个 Product。
BaseProduct
- BaseProductID
- BaseProductName
Product
- ProductID
- BaseProductID
- ProductName
我尝试从具有相同表但不同种子值的不同数据库向两个 table 中插入行。我不想保留源数据库中的 ID。
有没有办法在一条语句中做到这一点?
编辑
Select 会是
Select ProductName FROM @SourceProduct
WHERE Not ProductName in (
select ProductName FROM @TargetBaseProduct
)
我尝试了 Giorgi 的解决方案,它很接近,但是
的匹配tgt.BaseProductID = src.BaseProductID
如果目标已经有 BaseProductID = 1 的条目,则导致不插入 BaseProductID = 1 的源行的结果。
DECLARE @SourceBaseProduct TABLE
(
BaseProductID INT ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @SourceProduct TABLE
(
ProductID INT ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
DECLARE @TargetBaseProduct TABLE
(
BaseProductID INT IDENTITY(1, 1) ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @TargetProduct TABLE
(
ProductID INT IDENTITY(1, 1) ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
INSERT INTO @SourceBaseProduct
VALUES ( 1, 'BaseProduct1' ),
( 2, 'BaseProduct2' ),
( 4, 'BaseProduct3' )
INSERT INTO @SourceProduct
VALUES ( 3, 1, 'Product1' ),
( 9, 2, 'Product2' ),
( 27, 4, 'Product3' )
INSERT INTO @TargetBaseProduct
(
BaseProductName
)
VALUES ( 'Existing Product Base' )
INSERT INTO @TargetProduct(
BaseProductID ,
ProductName)
VALUES ( @@IDENTITY, 'Existing Product' )
MERGE INTO @TargetBaseProduct tgt
USING
( SELECT sbp.BaseProductID ,
sbp.BaseProductName ,
sp.ProductName
FROM @SourceBaseProduct sbp
JOIN @SourceProduct sp ON sp.BaseProductID = sbp.BaseProductID
) AS src
ON tgt.BaseProductID = src.BaseProductID
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES ( src.BaseProductName )
OUTPUT
Inserted.BaseProductID ,
src.ProductName
INTO @TargetProduct(BaseProductID, ProductName);
SELECT * FROM @TargetBaseProduct
SELECT * FROM @TargetProduct
输出
BaseProductID BaseProductName
1 Existing Product Base
2 BaseProduct2
3 BaseProduct3
ProductID BaseProductID ProductName
1 1 Existing Product
2 2 Product2
3 3 Product3
预期结果
BaseProductID BaseProductName
1 Existing Product Base
2 BaseProduct1
3 BaseProduct2
4 BaseProduct3
ProductID BaseProductID ProductName
1 1 Existing Product
2 2 Product1
3 3 Product2
4 4 Product3
编辑
使用
ON 1 = 0
按照 Giorgi 的建议给出了正确的结果
如果我没猜错,MERGE
:
DECLARE @SourceBaseProduct TABLE
(
BaseProductID INT ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @SourceProduct TABLE
(
ProductID INT ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
DECLARE @TargetBaseProduct TABLE
(
BaseProductID INT IDENTITY(1, 1) ,
BaseProductName NVARCHAR(MAX)
)
DECLARE @TargetProduct TABLE
(
ProductID INT IDENTITY(1, 1) ,
BaseProductID INT ,
ProductName NVARCHAR(MAX)
)
INSERT INTO @SourceBaseProduct
VALUES ( 1, 'BaseProduct1' ),
( 2, 'BaseProduct2' ),
( 4, 'BaseProduct3' )
INSERT INTO @SourceProduct
VALUES ( 3, 1, 'Product1' ),
( 9, 2, 'Product2' ),
( 27, 4, 'Product3' )
MERGE INTO @TargetBaseProduct tgt
USING
( SELECT sbp.BaseProductID ,
sbp.BaseProductName ,
sp.ProductName
FROM @SourceBaseProduct sbp
JOIN @SourceProduct sp ON sp.BaseProductID = sbp.BaseProductID
) AS src
ON tgt.BaseProductID = src.BaseProductID
WHEN NOT MATCHED BY TARGET THEN
INSERT VALUES ( src.BaseProductName )
OUTPUT
Inserted.BaseProductID ,
src.ProductName
INTO @TargetProduct(BaseProductID, ProductName);
SELECT * FROM @TargetBaseProduct
SELECT * FROM @TargetProduct
输出:
BaseProductID BaseProductName
1 BaseProduct1
2 BaseProduct2
3 BaseProduct3
ProductID BaseProductID ProductName
1 1 Product1
2 2 Product2
3 3 Product3
编辑:如果您也想插入现有行,则更改
ON tgt.BaseProductID = src.BaseProductID
到
ON 1 = 0