Застрял, пытаясь найти способ «psuedo внешний ключ» данных после вставки - PullRequest
0 голосов
/ 21 февраля 2012

Я работаю в SQL 2008 R2.В настоящее время я использую родительскую структуру записи в качестве шаблона для вставки копий структуры в качестве дочерних записей.У меня возникают проблемы при переходе на 3-й уровень данных и выше, поскольку я не могу придумать способ сделать пары данных уникальными.Позвольте мне объяснить с помощью иерархии:

Table
- Table_Level1_data (fk'd to Table)
-- Table_Level2_data (fk'd to Table_Level1_data but NOT to Table)

Записи в таблице имеют поле для parent_record_id, которое ссылается на одну и ту же таблицу, так что это помогает мне перейти на 2 уровня.Теперь вот что я делаю.(код упрощен для отображения здесь)

Сначала я вставляю нужные новые записи в таблицу, заполняя указанные поля данными из родительской записи.

INSERT INTO table
(field_names...)
SELECT
desired fields from target dataset
, fields from table
FROM table where record_id=@parentrecordid /* variable set to identify "template" record */

Далее я используюCTE, чтобы получить все записи в таблице, которые являются дочерними по отношению к моей родительской записи «шаблона», но еще не имеют каких-либо подробностей в таблице второго уровня.Затем я вставляю копии подробных данных родительских записей в таблицу следующего уровня для всех дочерних записей, захваченных в CTE.

;
WITH
   CTE (record_id, parent_record_id)
   AS
   (
       SELECT record_id, parent_record_id FROM table where record_id NOT IN (SELECT record_id FROM table_level1_data) AND record_id IN (SELECT record_id from table WHERE parent_record_id=@parentrecordid
   )

INSERT INTO table_level1_data
SELECT
data.fields
FROM table_level1_data data
JOIN CTE AS c ON data.record_id=c.parent_record_id

До этого момента все прекрасно работало.Проблема в том, что, как только я пытаюсь перейти на следующий уровень (вставка данных из идентификатора шаблона в table_level2_data для моих новых дочерних записей), соединение с уникальным идентификатором прекращается.Мне нужен какой-то способ для перекрестной ссылки на вновь созданный table_level1_data.data_id с соответствующим table_level1_data.parent_data_id (не существует после запуска CTE).Я ломал голову, пытаясь придумать способы создания временных таблиц или чего-либо еще, что позволило бы мне создать какой-то уникальный тип связи между вставленными мной данными уровня 1 и родительским идентификатором data_id, который соответствовал им во время вставки.Я даже рассматривал курсоры (RBAR был последним средством), но до сих пор не могу понять.

У кого-нибудь есть идеи?

Заранее спасибо.Это мой первый пост на этом сайте, но определенно не первый раз, когда я получаю от него чрезвычайно ценную помощь.

ОБНОВЛЕНИЕ: я нашел способ сделать это с помощью вложенного курсора (двойной удар).Теперь я использую не только RBAR, но и RBA (RBAR) R!Это единственное, что я мог придумать.У кого-нибудь есть более чистое решение?

ДОБАВЛЕНО 25.04.2012: Хорошо, вот ужасный код, использующий курсоры.Пожалуйста, смотрите мой комментарий, чтобы увидеть краткое объяснение этого кода: - ВСТАВЬТЕ СОСТОЯНИЯ РАБОЧЕГО ПОТОКА, ДЕЙСТВИЯ И НАСТРОЙКИ ДЕЙСТВИЙ ДЛЯ СОЗДАННЫХ ВИДОВ НАЗНАЧЕНИЯ

-- need variables for source state_id, newly created state_id, and also need these for
-- each action_id as well for the action settings
DECLARE @stateID INT, @newStateID INT, @actionID INT
, @newActionID INT,@newAssignmentTypeID INT

--outer cursor for the states
DECLARE stateCursor CURSOR FAST_FORWARD FOR
SELECT state_id, ct.assignment_type_id AS new_type_id FROM asgn_assignment_type_state ats
JOIN @childtypes AS ct ON ats.assignment_type_id=ct.parent_assignment_type_id 
OPEN stateCursor
FETCH NEXT FROM stateCursor INTO @stateID, @newAssignmentTypeID

WHILE @@FETCH_STATUS<>-1
BEGIN
        --add new state
    INSERT INTO asgn_assignment_type_state(assignment_type_id,state_order,state_name,user_can_select,action_assembly,increment_state)
    SELECT @newAssignmentTypeID,state_order,state_name,user_can_select,action_assembly,increment_state
    FROM asgn_assignment_type_state
    WHERE state_id=@stateID

    --get new state ID
    SET @newStateID = SCOPE_IDENTITY()

    --inner cursor for each action (for the action settings per action)
    DECLARE actionCursor CURSOR FAST_FORWARD FOR
    SELECT action_id FROM asgn_assignment_action aaa
    WHERE state_id=@stateID
    OPEN actionCursor
    FETCH NEXT FROM actionCursor INTO @actionID

    WHILE @@FETCH_STATUS<>-1
    BEGIN
        --add new action
        INSERT INTO asgn_assignment_action (state_id,action_order,action_assembly)
        SELECT @newStateID,action_order,action_assembly
        FROM asgn_assignment_action
        WHERE action_id=@actionID

        --get new action ID
        SET @newActionID = SCOPE_IDENTITY()

        --add settings
        INSERT INTO asgn_assignment_action_setting(action_id,name,value,type_id)
        SELECT @newActionID,name,value,type_id
        FROM asgn_assignment_action_setting
        WHERE action_id=@actionID


    FETCH NEXT FROM actionCursor INTO @actionID
    END
    CLOSE actionCursor
    DEALLOCATE actionCursor

    FETCH NEXT FROM stateCursor INTO @stateID, @newAssignmentTypeID
END
CLOSE stateCursor
DEALLOCATE stateCursor
...