Mysql
 sql >> Database >  >> RDS >> Mysql

Due query di inserimento con campi collegati

Qualche semplificazione è possibile. Prima di tutto devi racchiudere tutti i tuoi comandi all'interno di una transazione perché questo è il classico caso in cui i record inseriti sono in stretta relazione e non ha senso avere qualche set di record parzialmente completato.

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

Ora puoi modificare la tua domanda di inserimento sql per aggiungere una seconda istruzione che restituisce l'ultimo ID inserito

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

    ..

 }

Nota come, al costruttore MySqlCommand, viene passato il riferimento alla transazione corrente. Questo è necessario per funzionare con una connessione che ha una transazione aperta.

Le cose sono un po' più complesse per la seconda parte. Lo stesso trucco per aggiungere una seconda istruzione sql potrebbe essere applicato anche al ciclo che inserisce le risposte, ma è necessario tornare indietro se la prima domanda è quella corretta

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

Ora puoi eseguire l'ultimo comando che aggiorna la domanda con lastAnswerID

(Un'ultima nota, suppongo che i campi question_id e answer_id siano di tipo numerico, non varchar, questo richiede che i parametri per questi campi siano un Int32 non un varchar)