Используйте SQL для клонирования данных в двух таблицах, которые имеют отношение 1-1 друг к другу - PullRequest
0 голосов
/ 19 мая 2010

Использование MS SQL 2005,

Таблица 1

ID |  T1Value  | T2ID  |  GroupID
----------------------------------
1  |     a     |  10   |     1
2  |     b     |  11   |     1
3  |     c     |  12   |     1
4  |     a     |  22   |     2

Таблица 2

ID  |  T2Value
----------------
10  |     H
11  |     J
12  |     K
22  |     H

Я хочу клонировать данные для GroupID == 1 в новый GroupID, чтобы я получил следующее:

Таблица 1

ID |  T1Value  | T2ID  |  GroupID
----------------------------------
1  |     a     |  10   |     1
2  |     b     |  11   |     1
3  |     c     |  12   |     1
4  |     a     |  22   |     2
5  |     a     |  23   |     3
6  |     b     |  24   |     3
7  |     c     |  25   |     3

Таблица 2

ID  |  T2Value
----------------
10  |     H
11  |     J
12  |     K
22  |     H
23  |     H
24  |     J
25  |     K

Я нашел несколько шаблонов клонирования SQL, которые позволяют мне хорошо клонировать данные в одной и той же таблице ... но когда я начинаю работать с клонированием данных в двух таблицах одновременно, а затем корректно связывать новые строки. ... это не то, что я чувствую, что хорошо понимаю.

Я думал, что мог бы сделать несколько самостоятельных соединений, чтобы справиться с этим, но я обеспокоен случаями, когда неключевые поля содержат одни и те же данные в нескольких строках.

1 Ответ

1 голос
/ 20 мая 2010

Является ли мой единственный вариант использовать курсор для отслеживания отображения идентификатора? Вот некоторый псевдокод, который я написал ... еще не тестировал. Я надеялся на что-то более краткое. Это мой единственный вариант?

DECLARE @NewT2Key INT
DECLARE @OldT2Key INT
DECLARE @T2Value  VARCHAR(50)
DECLARE @T2KeyNewOld TABLE (OldT2Key INT, NewT2Key INT)

DECLARE @NewGroupID INT
DECLARE @OldGroupID INT

SET @NewGroupID = 3
SET @OldGroupID = 1

--
-- STEP 1: CLONE THE TABLE2 DATA AND KEEP MAPPING OF OLD-to-NEW IDs
--
DECLARE curT2Keys
CURSOR FAST_FORWARD LOCAL FOR
    SELECT t2.ID,
        t2.T2Value
    FROM dbo.Table2 t2
        JOIN dbo.Table1 t1
        ON  t2.ID    = t1.T2ID
    WHERE t1.GroupID = @OldGroupID
    ORDER BY t1.ID

OPEN curT2Keys
FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value

WHILE @@FETCH_STATUS = 0
BEGIN
    SET @NewT2Key = (SELECT MAX(ID)+1 FROM dbo.Table2)

    INSERT INTO dbo.Table2(ID, T2Value)
    VALUES(@NewT2Key, @T2Value)

    INSERT INTO @T2KeyNewOld(OldT2Key, NewT2Key)
    VALUES(@OldT2Key, @NewT2Key)

    FETCH NEXT FROM curT2Keys INTO @OldT2Key, @T2Value
END
CLOSE curT2Keys
DEALLOCATE curT2Keys

--
-- STEP 2: CLONE THE TABLE1 DATA AND UPDATE IDs WITH NEW MAPPING
--

      INSERT INTO dbo.Table1([ID], [T1Value], [T2ID], [GroupID])
      (SELECT
            (SELECT MAX(ID) FROM dbo.Table1) + ROW_NUMBER() OVER (ORDER BY GroupID),
            t1.[T1Value],
            t2.[NewT2Key],
            @NewGroupID
       FROM dbo.Table1 t1 
           JOIN @T2KeyNewOld t2
           ON t1.T2ID = t2.OldT2Key
       WHERE t1.GroupID = @OldGroupID
      )
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...