IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

ASP.NET Discussion :

Exécuter plusieurs requêtes parémétrées dans une même transaction


Sujet :

ASP.NET

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 37
    Points : 33
    Points
    33
    Par défaut Exécuter plusieurs requêtes parémétrées dans une même transaction
    Bonjour,

    je suis coincé pour exécuter une série de requête INSERT dans une boucle et je passe par des requêtes paramétrées.

    Alors quand je teste sans les paramètres ça passe mais avec non ou bien une seul commande isert ça passe

    voici un extrait du code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
     
     
    bool resultat = false;
    SqlCommand cmd2;
    SqlCommand cmd = new SqlCommand();
    cmd.CommandType = CommandType.Text;
    cmd.CommandText = "";
     
    string sql = "";
     
    foreach (Pole UnPole in ListePole)
    {
                sql += "INSERT INTO guides_poles (gup_gui_id, gup_pol_id) VALUES (@gup_gui_id, @gup_pol_id);";
     
                cmd2 = new SqlCommand();
                cmd2.CommandType = CommandType.Text;
                cmd2.CommandText = sql;
     
     
                // Création et déclaration des paramètres 
                cmd2.Parameters.Add(new SqlParameter("@gup_gui_id", System.Data.SqlDbType.Int));
                cmd2.Parameters.Add(new SqlParameter("@gup_pol_id", System.Data.SqlDbType.Int));
     
                // Attribution des valeurs aux paramètres 
                cmd2.Parameters["@gup_gui_id"].Value = UnGuide.gui_id;
                cmd2.Parameters["@gup_pol_id"].Value = UnPole.pol_id;
     
                cmd.CommandText += cmd2.CommandText;
    }
     
     
            try
            {
                cmd.Connection = Connexion.Instance.getConnexion();
                cmd.Connection.Open();
                cmd.ExecuteNonQuery();
                resultat = true;
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
                System.Diagnostics.Debug.Print("Erreur SQL");
            }
            finally
            {
                cmd.Connection.Close();
            }...

    donc je voudrais appeler cmd.CommandText une seul fois

    est ce que vous voyez ce qui ne va pas?

    merci d'avance.

  2. #2
    Membre confirmé

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 244
    Points : 574
    Points
    574
    Par défaut
    Hello,

    T'a essayé de regarder le résultat de ta requête en mode DEBUG ?
    A mon avis, si tu le fais, tu verras direct un premier problème : à savoir, la variable "sql" n'étant pas réinitialisée à chaque passage dans la boucle, tu cumules 2 fois plus de "INSERT" que nécessaire...
    Ensuite, l'utilisation de SqlParameter nécessite des noms de variable @... différents dans toute la requête (ou en tout cas pour tout appel de ExecuteNonQuery()). Tu ne peux donc pas la construire comme cela, il serait préférable dans ce cas, d'inclure chaque appel d'exécution de requête dans le foreach(...).
    Enfin, ce n'est pas parce que tu exécute plusieurs INSERT en une seule commande que tu es en mode transactionnel. Tu dois utiliser un SqlTransaction (ou un TransactionScope).

    En gros, tu devrais avoir un truc comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
     
    // en utilisant le using, la connection sera fermée automatiquement
    using (SqlConnection connection = Connexion.Instance.getConnexion())
    {
    	connection.Open();
    	using (SqlTransaction transaction = connection.BeginTransaction())
    	{
    		try
    		{
    			foreach (Pole UnPole in ListePole)
    			{
    				SqlCommand cmd = new SqlCommand();
    				cmd.Connection = connection;
    				com.Transaction = transaction;
    				cmd.CommandType = CommandType.Text;
    				cmd.CommandText = "INSERT INTO guides_poles (gup_gui_id, gup_pol_id) VALUES (@gup_gui_id, @gup_pol_id);";
     
    				// Création et déclaration des paramètres
    				cmd.Parameters.Add(new SqlParameter("@gup_gui_id", System.Data.SqlDbType.Int));
    				cmd.Parameters.Add(new SqlParameter("@gup_pol_id", System.Data.SqlDbType.Int));
     
    				// Attribution des valeurs aux paramètres
    				cmd.Parameters["@gup_gui_id"].Value = UnGuide.gui_id;
    				cmd.Parameters["@gup_pol_id"].Value = UnPole.pol_id;
    				cmd.ExecuteNonQuery();
    			}
     
    			transaction.Commit();
    		}
    		catch (Exception ex)
    		{
    			// pour gérer les exceptions dues à une perte de connexion
    			if (transaction.Connection != null) 
    			{
    				transaction.Rollback();
    			}
     
    			Console.WriteLine(ex.Message);
    			System.Diagnostics.Debug.Print("Erreur SQL");
     
    			// ça peut être pas mal de lancer une nouvelle exception personnalisée ici plutôt qu'utiliser un booléen
    			throw new InsertionImpossibleException("Insertion impossible... blabla...", ex);
    		}
    	}
    }
    Enfin à la louche, j'ai pas testé.
    "C'est tellement merdique que toute modification est une amélioration !"

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 37
    Points : 33
    Points
    33
    Par défaut
    merci pour la réponse,

    Effectivement la variable sql était à réinitialiser j'avais corrigé ça. J'ai du faire comme tu le décris en mettant l'exécution de la requête dans la boucle.

    Par contre le commit et le rollback ça m'intéresse. Car mon souhait c'est que tout est commité seulement si tous les INSERT sont passé avec succès.

    dans ta réponse j'ai l'impression que le commit se fait au fur et à mesure. Il faudrait que je commit en dehors de la boucle je pense.

  4. #4
    Membre confirmé

    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Novembre 2011
    Messages
    244
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Âge : 46
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2011
    Messages : 244
    Points : 574
    Points
    574
    Par défaut
    Héhé, non... mon commit est bien en dehors de la boucle (mais j'aurais pu me tromper, il est vrai )

    Par contre j'aurais pu faire un :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    using(SqlCommand cmd = new SqlCommand())
    {
    	...
    }
    C'est quand même mieux...
    "C'est tellement merdique que toute modification est une amélioration !"

  5. #5
    Nouveau membre du Club
    Homme Profil pro
    Inscrit en
    Avril 2012
    Messages
    37
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Avril 2012
    Messages : 37
    Points : 33
    Points
    33
    Par défaut
    Désolé j'ai mal lu.

    Il me reste juste à faire un jeu d'essai pour tester le commit et le rollback

    merci beaucoup!

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 20/04/2011, 11h20
  2. Réponses: 10
    Dernier message: 12/05/2010, 11h10
  3. Réponses: 1
    Dernier message: 26/03/2009, 16h56
  4. Requête imbriquée dans une même table
    Par casavba dans le forum Langage SQL
    Réponses: 3
    Dernier message: 09/01/2008, 21h02
  5. Réponses: 1
    Dernier message: 07/08/2007, 09h06

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo