如何使用T-SQL复制数据?

时间:2009-06-11 05:34:26

标签: sql tsql

我有名为CategoriesQuestionsSelections的表格。表格的关系是:Selections中可以有一个或多个QuestionQuestions中可以有一个或多个Category

表格列如下:

  

分类
    - CategoryID(pk)
    - 姓名

     

问题
    - QuestionID(pk)
    - 问题
    - CategoryID(fk)

     

选择
    - SelectionID(pk)
    - 选择
    - QuestionID(fk)

我想将此代码从C#转换为SQL:

private int fromCategoryID = 1;
private int toCategoryID = 2;

Category cat1 = new Category(); //this is the category we will get questions from.
Category cat2 = new Category(); //this is the category we copy the questions to.

// code to populate the 2 category instances and their children (Questions) and
// children's children (Selections) removed for brevity.

// copy questions and selections from cat1 to cat2
foreach(Question q from cat1.Questions)
{
Question newQuestion = new Question();
newQuestion.Question = q.Question;

foreach(Selection s in q.Selections)
{
Selection newSelection = new Selection();
newSelection.Selection = s.Selection;

q.Selections.Add(newSelection);
}

cat2.Questions.Add(newQuestion);
}

如何在SQL中完成?

3 个答案:

答案 0 :(得分:2)

如果您想同时提供问题和选择,则需要2个插入。 基于假设问题在一个类别中是唯一的,这将做你想要的。

declare @FromCategoryId int
declare @NewCategoryId int

set @NewCategoryId = 3
set @FromCategoryId = 2

insert into Questions 
select Question, @NewCategoryId
from Questions
where CategoryId = @FromCategoryId

insert into Selections
select S.Selection, QNew.QuestionId
from Questions QOld
join Questions QNew
on QOld.Question = QNew.Question
and QOLD.CategoryId = @FromCategoryId
and QNEW.CategoryId = @NewCategoryId
join Selections S
on S.QuestionId = QOld.QuestionId

否则,您使用给定类别的选择和问题填充的一些临时表然后将它们推送到真实表也可能有效。

答案 1 :(得分:1)

T-SQL中的插入/选择语法可能会给你一个开始:

您可以从表格中选择某些列以及一些手工设置的值,然后将它们重新插入表格中:

这是一个简单的例子(可能不完全是你想要的):

insert into [Questions] (Question, CategoryID)
select Question, @Category2ID
from [Questions]
where CategoryID = @Category1ID

答案 2 :(得分:1)

假设QuestionID和SelectionID是IDENTITY列,你可以做这样简单的事情:

INSERT INTO Questions (Question,CategoryID) 
SELECT q.Question, 2
FROM Questions q
WHERE q.CategoryID = 1

将所有问题从第1类​​复制到第2类。

问题在于复制选择,因为您没有任何方法将问题与其选择相关联。因此,您可以说“从类别1中的所有问题中获取所有选择”,但您无法知道第2类中这些问题的新QuestionID。

根据您提供的架构,我将解决此问题的方法是编写一个存储过程,以与C#伪代码完全相同的方式迭代要复制的问题。虽然有些人讨厌在T-SQL中使用CURSOR的想法,但这就是它的用途。在黑暗中(未经测试)粗略刺伤将是这样的:

CREATE PROCEDURE PrcCopyQuestions (
    @CategoryID_from NUMERIC
    @CategoryID_to   NUMERIC
)
AS
DECLARE

@old_QuestionID NUMERIC(10,0)
@new_QuestionID NUMERIC(10,0)
@Question       VARCHAR(255)

DECLARE c_questions CURSOR FOR
    SELECT  QuestionID, Question
    FROM    Questions
    WHERE   CategoryID = @CategoryID_from
    FOR READ ONLY

BEGIN
    OPEN c_questions
    WHILE (1=1)
    BEGIN
        FETCH c_questions INTO @old_QuestionID, @Question
        IF @@SQLSTATUS <> 0 BREAK

        INSERT INTO Questions (Question,CategoryID) 
        SELECT @Question, @CategoryID_to

        SELECT @new_QuestionID = @@IDENTITY

        INSERT INTO Selections (Selection, QuestionID)
        SELECT s.Selection, @new_QuestionID
        FROM Selections s
        WHERE QuestionID = @old_QuestionID

    END

    CLOSE c_questions
    DEALLOCATE CURSOR c_questions
END