Я работаю в 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