2009-06-11 30 views
1

我有表名为Categories,QuestionsSelections。这些表格的关系是:在Question中可以有一个或多个Selections,并且在Category中可以有一个或多个Questions如何使用T-SQL复制数据?

表列如下:

分类
- 类别ID(PK)
- 名称

问题
- QuestionID(PK)
- 问题
- 类别ID( 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中?

+0

我们在这里谈论的是什么样的PK? – 2009-06-11 05:50:07

+0

您的意思是PK的数据类型?这是一个身份播种PK(int)。 – jerbersoft 2009-06-11 06:29:09

+0

什么版本的SQL Server? – HLGEM 2009-06-11 13:24:06

回答

1

假设QuestionID和SelectionID是IDENTITY列,你可以做一些简单的像这样:

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

这将全部来自第1类的问题复制到第2类

问题带有复制选项,你没有一个相关的问题是选择的任何方式。因此,您可以说“让我从所有类别1中的所有问题中选择所有选项”,但是您无法知道类别2中的那些问题的新问题ID。

根据您所拥有的架构提供的方式,我将解决这个问题的方法是编写一个存储过程,该存储过程以与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 
1

在T-SQL插入/ select语法可能会给你一个开始:

可以从表中选择某些列,并通过手动设定值一起,然后将它们放回表:

下面是一个简单的例子(可能不是你想要什么):

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

您将需要2个插入,如果你想既带来了问题和整个选择。 基于Question在一个类别中是唯一的这一假设,它会做你想做的事情。

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 

否则一些临时表,其中填充给定类别的选择和问题然后将它们推送到真正的表也可能工作。