在插入期间,将主键从目标表复制为源表上的外键

时间:2013-02-06 18:31:00

标签: sql-server sql-server-2008 tsql

情况:
我将信息从一个表插入另一个表,一个源和目标。将信息插入目标时,将创建主键。 (在这种情况下,它是一个整数。)然后我需要能够绑定到源表。但是,根据移动的数据,我无法可靠地获得目标和源表之间的1:1匹配。

问题:
有没有办法复制在目标表中为记录(x)创建的主键,并在发生批量插入时将其作为外键复制到源表中的同一记录(x)?

详细信息:
我想在SQL中完成这个。我有一个解决这个问题的方法,但我认为必须有办法做我正在问的问题。

3 个答案:

答案 0 :(得分:2)

我在阅读这篇精彩的文章后找到了答案。

http://sqlblog.com/blogs/adam_machanic/archive/2009/08/24/dr-output-or-how-i-learned-to-stop-worrying-and-love-the-merge.aspx

我使用MERGE及其OUTPUT子句实现了我所寻找的目标。这是我用来解决这个问题的示例代码。

我首先创建了3个临时表,#Temp2,#Temp3和#Temp4。 #Temp2被认为是源表。 #Temp3将是目标表,#Temp4是一个桥。然后我插入了几行非常简单的数据,在这种情况下只有一个字段 - 值。

CREATE TABLE #Temp2(
OldID INT IDENTITY(1,1),
Value INT,
NewFK INT)

CREATE TABLE #Temp3(
NewerID INT IDENTITY(1,1),
Value INT)

CREATE TABLE #Temp4(
OldID INT NOT NULL,
NewerID INT NOT NULL,
Value INT)

INSERT INTO #Temp2(Value)
VALUES(30), (40), (50), (70)

INSERT INTO #Temp3(Value)
VALUES (333), (444), (555), (777)

然后是MERGE声明,它执行脏工作。它将从#Temp2获取值并将其放入#Temp3。然后它将获取#Temp3中创建的ID,#Temp2中的ID和传递的值,并将它们全部输入#Temp4。

MERGE INTO #Temp3 AS tgt
USING #Temp2 AS src
ON 1=0
WHEN NOT MATCHED THEN
    INSERT(
    Value)
    VALUES(
    src.Value)
OUTPUT
    src.OldID,
    INSERTED.NewerID,
    src.Value
INTO #Temp4(OldID, NewerID, Value);

然后我向临时表#Temp2运行UPDATE以使用新ID更新NewFK字段。最后,做一个简单的SELECT来查看更新的信息。

UPDATE X
SET X.NewFK = Z.NewerID
FROM #Temp2 X
JOIN #Temp4 Z
ON X.OldID = Z.OldID

SELECT * FROM #Temp2

这正是我所需要的,并且是一种非常精简的做事方式。我希望这会帮助一些遇到这个问题的人。感谢大家的见解和回应。

注意: 我相信MERGE是在SQL Server 2008中引入的。

乔纳森

答案 1 :(得分:0)

一种方法是将目标表的标识插入设置为“开启”(http://msdn.microsoft.com/en-us/library/ms188059.aspx)。然后在运行插入之前将该标识作为“源”数据的一部分。只要记得在完成后再将身份插入关闭。

修改
不确定你的情况是什么,但我过去采用的一个方法是创建一个字段来保存“外部源ID”,以防万一我需要在将来的某个时候回溯到源代码。就我而言,这仅供参考,而非正常的交易使用。

答案 2 :(得分:0)

如果您可以在目标中获得SharedExtPK,那么这应该有用 在这种情况下,logID是源的PK 测试:

DECLARE @MyTableVar table(
  TargetPK     int NOT NULL,
  SourcePK     int NOT NULL
  );

INSERT INTO IdenOutPut (someValue, sharedExtKey)
  OUTPUT INSERTED.iden, 
         INSERTED.sharedExtKey
  INTO @MyTableVar
    SELECT name, logID
    FROM CatID

update sPK 
set sPK.ExtPK = tTbl.TargetPK
FROM @MyTableVar as tTbl 
JOIN CatID as sPK 
  on sPK.logID = tTbl.SourcePK 
GO

如果您插入的值是唯一的,那么可以使用它 但它会变得更棘手。