我有名为Categories
,Questions
和Selections
的表格。表格的关系是:Selections
中可以有一个或多个Question
,Questions
中可以有一个或多个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中完成?
答案 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