Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Zwei Insert-Abfragen mit verknüpften Feldern

Einige Vereinfachungen sind möglich. Zunächst müssen Sie alle Ihre Befehle in eine Transaktion einschließen, da dies der klassische Fall ist, in dem die eingefügten Datensätze in strengen Beziehungen stehen und es keinen Sinn macht, einen teilweise vollständigen Satz von Datensätzen zu haben.

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

Jetzt könnten Sie Ihre SQL-Frage zum Einfügen ändern, um eine zweite Anweisung hinzuzufügen, die die zuletzt eingefügte ID zurückgibt

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

    ..

 }

Beachten Sie, wie beim MySqlCommand-Konstruktor die Referenz auf die aktuelle Transaktion übergeben wird. Dies ist erforderlich, um mit einer Verbindung zu arbeiten, die eine Transaktion geöffnet hat.

Beim zweiten Teil wird es etwas komplexer. Der gleiche Trick, um eine zweite SQL-Anweisung hinzuzufügen, könnte auch auf die Schleife angewendet werden, die die Antworten einfügt, aber Sie müssen zurückschleifen, wenn die erste Frage die richtige ist

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

Jetzt könnten Sie den letzten Befehl ausführen, der die Frage mit der lastAnswerID

aktualisiert

(Eine letzte Anmerkung, ich nehme an, dass die Felder question_id und answer_id vom Typ numerisch sind, nicht varchar, dies erfordert, dass die Parameter für diese Felder ein Int32 und kein varchar sind)