2009-06-11 51 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 

否則一些臨時表,其中填充給定類別的選擇和問題然後將它們推送到真正的表也可能工作。