在多对多关系中引用的重复记录

时间:2013-03-04 16:55:30

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

我目前正在编写一个存储过程,它会创建现有对象的精确副本。 该对象使用多个表,其中2个表使用多对多关系:

以下是使用的架构:

---------------------------------------
          tbl_AssociationA
---------------------------------------
ID  |  ObjectID |    Description
---------------------------------------
1   |  12       |    'Some description'
2   |  12       |    'Some text here'
3   |  13       |    'Some words here'
               ...
---------------------------------------


---------------------------------------
          tbl_AssociationB
---------------------------------------
ID  |  ObjectID |    LabelText
---------------------------------------
1   |  12       |    'Foo'
2   |  12       |    'Foo foo'
3   |  13       |    'Some words...'
4   |  13       |    'Some other Foos'
5   |  14       |    'Some foos here'
6   |  12       |    'Some other words'
               ...
---------------------------------------


-------------------------
    tbl_RelationAB
-------------------------
ID_A      |  ID_B
-------------------------
1         |  1     
2         |  1    
2         |  2     
2         |  6     
3         |  4      
3         |  3      
          ...
------------------------

现在,假设我要创建Object 12的副本(我们称之为Object X)。我想要复制tbl_AssociationAtbl_AssociationB的记录,因为我不希望对Object X进行进一步修改以修改Object 12

因此,要在tbl_AssociationAtbl_AssociationB中创建新记录,我会使用此方法:

INSERT INTO tbl_AssociationA
SELECT @NewId,Description FROM tbl_AssociationA WHERE ObjectID=@NewId;

INSERT INTO tbl_AssociationB
SELECT @NewId,LabelText FROM tbl_AssociationB WHERE ObjectID=@NewId;

如何使用新创建的记录插入tbl_RelationAB。请注意,IDtbl_AssociationA中的tbl_AssociationB列为IDENTITY

2 个答案:

答案 0 :(得分:2)

我正在重复使用同一张桌子而没有插入。
但这显示了如何检索两个iden并在声明中使用它们。

  set nocount on;
  declare @idenA SmallInt, @idenB SmallInt; 
  insert into Table_1(value) values('a');
  set @idenA = scope_identity();
  insert into Table_1(value) values('b');
  set @idenB = scope_identity();
  print @idenA;
  print @idenB;

  insert into Table_1 (value)
  OUTPUT inserted.* 
  select top 2 value from Table_1 

但我明白这不是你问题的完整答案 我想你需要输出到临时表 一旦你得到了更好的答案,我将删除这个。

答案 1 :(得分:2)

好的,这笔交易是:

  

我想将对象X复制到对象Z.   对象X在tbl_AssociationAtblAssociationB中使用外键ObjectID引用。   第3个表格tbl_RelationAB指定tbl_AssociationA.IDtbl_AssociationB.ID之间的多对多映射。

在此解决方案中,对象X引用@originalObjectID,对象Z引用@copiedObjectID。 2个临时表@TempA@TempB用于保留IDtbl_AssociationA的旧的和新的自动生成的tbl_AssociationB列之间的映射。< / p>

DECLARE @TempA AS TABLE (newID INT, oldID INT);
DECLARE @TempB AS TABLE (newID INT, oldID INT);

MERGE tbl_AssociationA AS tbl_a
USING (
    SELECT ID, ObjectID, Description
    FROM tbl_AssociationA WHERE ObjectID=@originalObjectID
) as old_tbl_a
ON 1=0
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (ObjectID,Description) VALUES (@copiedObjectID,Description)
    OUTPUT INSERTED.ID,old_tbl_a.ID INTO @TempA;

MERGE tbl_AssociationB AS tbl_b
USING (
    SELECT ID, ObjectID, LabelText
    FROM tbl_AssociationB WHERE ObjectID=@originalObjectID
) as old_tbl_b
ON 1=0
WHEN NOT MATCHED BY TARGET THEN 
    INSERT (ObjectID,LabelText) VALUES (@copiedObjectID,LabelText)
    OUTPUT INSERTED.ID,old_tbl_b.ID INTO @TempB;

INSERT INTO tbl_RelationAB
SELECT a.newID,b.newID
FROM tbl_RelationAB tbl_ab
INNER JOIN @TempA a ON tbl_ab.ID_A = a.oldID
INNER JOIN @TempB b ON tbl_ab.ID_B = b.oldID;

因此,表tbl_RelationAB也会复制新自动生成的tbl_AssociationA.IDtbl_AssociationB.ID之间的关系。希望这可以帮助将来的某个人!