Каскадная копия строк в sql - PullRequest
3 голосов
/ 18 июля 2011

Я нашел эту тему здесь: http://www.sqlteam.com/forums/topic.asp?TOPIC_ID=16836 У меня точно такая же проблема.Цитата:

Роб Пирмен пишет: «У меня есть 3 таблицы с вопросами.

Таблица 1: Вопрос

Поле: ID (Уникальный) Поле: Имя (Текст)

Таблица 2: Текст вопроса (Ссылки Table1-ID)

Поле: ID (Уникальный) Поле: QuestionID (целое число относительно идентификатора Table1 ID) Поле: Текст

Таблица 3: Параметры

Поле: ID (уникальный) Поле: QuestionTextID (целочисленный код для идентификатора таблицы 2) Поле: Текст

Скажем, например, я создаю вопрос с 2Записи с текстом вопроса и записи с 5 вариантами. Если я хотел продублировать этот вопрос на новый вопрос и скопировать записи с текстом вопроса на новые идентификаторы и все связанные параметры, как я могу это сделать легко (так как дублирующий вопрос будет иметьновый идентификатор, каждый из дублированных текстов вопросов будет иметь новые идентификаторы, как и каждый из вариантов). "

Предлагаемое решение:

create procedure CopyQuestion
@idtocopy int
AS
declare @tempquestionid
declare @tempquestiontextid
declare @questiontextid

insert into question (name)
     select name from question where id = @idtocopy

select @tempquestionid = @@identity

declare question_cursor cursor for
     select id from [question text] where id = @idtocopy
open question_cursor
fetch next from question_cursor into @questiontextid
while @@fetch_status = 0
begin
   insert into [question text] (questionid, text)
      select @tempquestionid, text from [question text] where id = @questiontextid
   select @tempquestiontextid = @@identity
      insert into [options] (questiontextid, text)
   select @tempquestiontextid, text from [options] where questiontextid = @questiontextid
   fetch next from question_cursor into @questiontextid
end
close question_cursor
deallocate question_cursor

Есть ли лучшийрешение этой проблемы?Я буду использовать триггер вставки.Спасибо!

Ответы [ 2 ]

4 голосов
/ 18 июля 2011

Вы можете использовать оператор merge с предложением output, чтобы получить соответствие между старым и новым идентификатором в questionText. Это описано в этом вопросе Использование merge..output для получения сопоставления между source.id и target.id .

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

create procedure CopyQuestion
  @idtocopy int
as

declare @QuestionID int

insert into question
select Name 
from question 
where ID = @idtocopy

select @QuestionID = scope_identity() 

declare @IDs table (NewQID int, OldQID int)

merge questionText as T
using (select ID, @QuestionID as QuestionID, Field
       from questionText
       where QuestionID = @idtocopy) as S
on 0=1
when not matched then
  insert (QuestionID, Field) values (QuestionID, Field)
output inserted.ID, S.ID   into @IDs;       

insert into options
select 
    I.NewQID,
    O.Field
from options O
  inner join @IDs as I
    on O.QuestionTextID = I.OldQID
0 голосов
/ 18 июля 2011

Это еще один способ сделать то же самое, немного более на основе набора. В моем примере ниже я использовал временную таблицу для сопоставления идентификаторов между двумя новыми таблицами. Также, пожалуйста, удалите пробелы из имен ваших таблиц (только потому, что вы можете не означать, что вы должны).

CREATE PROCEDURE udf_COPY_QUESTION 
@ID_TO_COPY int
 as 
BEGIN TRANSACTION
BEGIN TRY
DECLARE @NEW_QUESTION_ID INT, @MAX_ID INT
insert into question (name)
     select name from question where id = @ID_TO_COPY
SET @NEW_QUESTION_ID = SCOPE_IDENTITY()
SET @MAX_ID =IDENT_CURRENT( 'question text' )
select @NEW_QUESTION_ID AS questionid,
       Text,
       ROW_NUMBER() OVER (ORDER NAME) + @MAX_ID as new_text_id, 
       id as old_text_id
 INTO  #TEMP  from [question text] 
      where questionid = @ID_TO_COPY         
insert into [question text] (QuestionID,Text)
      select questionid,Text from #TEMP 
      order by new_text_id
insert into Options  (questiontextid, text) 
      select t.new_text_id,o.Text from options o
      inner join #temp t on t.old_text_id = o.questiontextid
COMMIT TRANSACTION
END TRY
BEGIN CATCH
    RAISERROR('COPY FAILED',10,1)
    ROLLBACK TRANSACTION 
END CATCH    
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...