sql >> Base de Datos >  >> RDS >> Mysql

Dos consultas de inserción con campos vinculados

Cierta simplificación es posible. En primer lugar, debe encerrar todos sus comandos dentro de una transacción porque este es el caso clásico en el que los registros insertados están estrictamente relacionados y no tiene sentido tener un conjunto de registros parcialmente completado.

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

Ahora, puede cambiar su insert question sql para agregar una segunda declaración que devuelva la última identificación insertada

 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());

    ..

 }

Observe cómo, en el constructor MySqlCommand, se pasa la referencia a la transacción actual. Esto es necesario para trabajar con una conexión que tenga una transacción abierta.

Las cosas son un poco más complejas para la segunda parte. El mismo truco para agregar una segunda instrucción sql podría aplicarse también al bucle que inserta las respuestas, pero debe retroceder si la primera pregunta es la correcta

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());
    }
    ....
}

Ahora puede ejecutar el último comando que actualiza la pregunta con lastAnswerID

(Una última nota, supongo que los campos question_id y answer_id son de tipo numérico, no varchar, esto requiere que los parámetros para estos campos sean Int32 no varchar)