两个带有链接字段的插入查询 [英] Two insert queries with linked fields

查看:39
本文介绍了两个带有链接字段的插入查询的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下两个 MySQL 表:

I have the following two MySQL tables:

questions:
question_id (PK, AI), module_id (FK), author_id (FK), approved, question, correct_answer_id (FK)

answers:
answer_id (PK, AI), question_id (FK), answer

我希望能够在问题"表中插入一个新行,并在答案"表中插入多行.

I want to be able to insert a new row in the 'questions' table and multiple rows in the 'answers' tables.

'answers' 表中的新行应与 'questions' 行中新生成的 'question_id' 值具有相同的 'question_id'.此外,questions"表中的correct_answer_id"字段应等于answers"表中插入的第一行的answer_id".

The new rows in the 'answers' table should have the same 'question_id' as the newly generated 'question_id' value in the 'questions' row. Also, the 'correct_answer_id' field in the 'questions' table should equal the 'answer_id' of the first row inserted in the 'answers' table.

是否有比以下步骤更有效的方法?:

Is there a more efficiently way to do this than the following steps?:

  • 插入值(module_id、author_id、approved、question)'问题'
  • 获取questions"中的最后一个question_id"
  • 在answers"中插入值(question_id、answer)
  • 更新问题"中的值 (correct_answer_id)

代码:

    string connStr = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
    MySqlConnection conn = new MySqlConnection(connStr);

    string queryUpdateQuestions = "INSERT INTO questions (module_id, author_id, approved, question) VALUES (@module_id, @author_id, @approved, @question)";
    MySqlCommand cmdUpdateQuestions = new MySqlCommand(queryUpdateQuestions, conn);
    cmdUpdateQuestions.Parameters.Add("@module_id", MySqlDbType.VarChar);
    cmdUpdateQuestions.Parameters["@module_id"].Value = ddlModules.SelectedValue.ToString();
    cmdUpdateQuestions.Parameters.Add("@author_id", MySqlDbType.VarChar);
    cmdUpdateQuestions.Parameters["@author_id"].Value = Session["UserID"].ToString();
    cmdUpdateQuestions.Parameters.Add("@approved", MySqlDbType.VarChar);
    cmdUpdateQuestions.Parameters["@approved"].Value = 'N';
    cmdUpdateQuestions.Parameters.Add("@question", MySqlDbType.VarChar);
    cmdUpdateQuestions.Parameters["@question"].Value = txtQuestion.Text;

    try
    {
        conn.Open();
        cmdUpdateQuestions.ExecuteNonQuery();
    }
    catch
    {
        lblError.Text="Unable to add question.";
    }
    finally
    {
        conn.Close();
    }

    //????? = get last question_id in 'questions'

    int a = Convert.ToInt32(ddlNoOfAnswers.SelectedValue.ToString());

    for (int b=1; b <= a; b++)
    {
        string queryUpdateAnswers = "INSERT INTO answers (question_id, answer) VALUES (@question_id, @answer)";
        MySqlCommand cmdUpdateAnswers = new MySqlCommand(queryUpdateAnswers, conn);
        cmdUpdateAnswers.Parameters.Add("@answer", MySqlDbType.VarChar);
        cmdUpdateAnswers.Parameters["@answer"].Value = ((TextBox)this.FindControl("txtAnswer" + b)).Text;
        cmdUpdateAnswers.Parameters.Add("@question_id", MySqlDbType.VarChar);
        cmdUpdateAnswers.Parameters["@question_id"].Value = ?????;

        try
        {
            conn.Open();
            cmdUpdateAnswers.ExecuteNonQuery();
        }
        catch
        {
            lblError.Text="Unable to add answer.";
        }
        finally
        {
            conn.Close();
        }
    }

    //update 'correct_answer_id' in 'questions'

推荐答案

可以进行一些简化.首先,您需要将所有命令包含在一个事务中,因为这是插入的记录之间存在严格关系的典型情况,并且拥有一些部分完成的记录集是没有意义的.

Some simplification is possible. First of all you need to enclose all of your commands inside a transaction because this is the classical case where the records inserted are in strictly relationships and it doesn't make sense to have some partially completed set of records.

using(MySqlConnection conn = new MySqlConnection(connStr))
{
    conn.Open();
    using(MySqlTransaction tr = conn.BeginTransaction())
    {
        ...
        // MySqlCommand code  goes here
        ...
        tr.Commit();
   }
}

现在,您可以更改插入问题 sql 以添加第二条语句,该语句返回最后插入的 id

Now, you could change your insert question sql to add a second statement that returns the last id inserted

 string queryUpdateQuestions = @"INSERT INTO questions (.....);
                                 SELECT LAST_INSERT_ID()";

 using(MySqlCommand cmdUpdateQuestions = new MySqlCommand(queryUpdateQuestions, conn, tr))
 {
    // build the parameters for the question record
    ......

    // Instead of ExecuteNonQuery, run ExecuteScalar to get back the result of the last SELECT
    int lastQuestionID = Convert.ToInt32(cmdUpdateQuestions.ExecuteScalar());

    ..

 }

注意在 MySqlCommand 构造函数中如何传递对当前事务的引用.这是处理已打开事务的连接所必需的.

Notice how, at the MySqlCommand constructor, is passed the reference to the current transaction. This is required to work with an connection that has a transaction opened.

第二部分的情况有点复杂.添加第二个 sql 语句的相同技巧也可以应用于插入答案的循环,但如果第一个问题是正确的,则需要向后循环

Things are a bit more complex for the second part. The same trick to add a second sql statement could be applied also to the loop that insert the answers, but you need to loop backward if the first question is the correct one

string queryUpdateAnswers = @"INSERT INTO answers (question_id, answer) 
                             VALUES (@question_id, @answer);
                             SELECT LAST_INSERT_ID()";

using(MySqlCommand cmdUpdateAnswers = new MySqlCommand(queryUpdateAnswers, conn, tr))
{
    // next move the loop inside the using and prepare the parameter before looping to  
    // to avoid unnecessary rebuild of the parameters and the command
    cmdUpdateAnswers.Parameters.Add("@answer", MySqlDbType.VarChar);
    cmdUpdateAnswers.Parameters.Add("@question_id", MySqlDbType.Int32);

    int lastAnswerID = 0;  
    // Loop backward so the last answer inserted is the 'correct' one and we could get its ID
    for (int b=a; b >= 1; b--)
    {
         cmdUpdateAnswers.Parameters["@answer"].Value = ((TextBox)this.FindControl("txtAnswer" + b)).Text;
         cmdUpdateAnswers.Parameters["@question_id"].Value = lastQuestionID;
         lastAnswerID = Convert.ToInt32(cmdUpdateAnswers.ExecuteScalar());
    }
    ....
}

现在您可以运行最后一个命令,使用 lastAnswerID 更新问题

Now you could run the last command that update the question with the lastAnswerID

(最后一点,我假设字段 question_id 和 answer_id 是数字类型,而不是 varchar,这要求这些字段的参数是 Int32 而不是 varchar)

(A last note, I suppose that the fields question_id and answer_id are of type numeric, not varchar, this requires that the parameters for these fields will be an Int32 not a varchar)

这篇关于两个带有链接字段的插入查询的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆