sql >> Database >  >> RDS >> Mysql

Twee invoegquery's met gekoppelde velden

Enige vereenvoudiging is mogelijk. Allereerst moet je al je commando's insluiten in een transactie, omdat dit het klassieke geval is waarin de ingevoegde records in strikte relaties staan ​​en het geen zin heeft om een ​​gedeeltelijk voltooide set records te hebben.

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

Nu zou u uw invoegvraag sql kunnen wijzigen om een ​​tweede instructie toe te voegen die de laatst ingevoegde id retourneert

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

    ..

 }

Merk op hoe bij de MySqlCommand-constructor de verwijzing naar de huidige transactie wordt doorgegeven. Dit is vereist om te werken met een verbinding waarbij een transactie is geopend.

Voor het tweede deel ligt het iets ingewikkelder. Dezelfde truc om een ​​tweede sql-instructie toe te voegen kan ook worden toegepast op de lus waarin de antwoorden worden ingevoegd, maar u moet achteruit gaan als de eerste vraag de juiste is

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

Nu zou je de laatste opdracht kunnen uitvoeren die de vraag bijwerkt met de lastAnswerID

(Een laatste opmerking, ik veronderstel dat de velden vraag_id en antwoord_id van het type numeriek zijn, niet varchar, dit vereist dat de parameters voor deze velden een Int32 zijn en geen varchar)



  1. MySQL ATAN() Functie - Retourneer de boogtangens van een waarde (of waarden)

  2. Geavanceerde failover met behulp van post/pre-script hooks

  3. Ajax-oproep retourneert de hele pagina in plaats van alleen de echo-waarde

  4. Waarom MySQL COUNT zonder tabelnaam 1 geeft