Probleme de connexion ouverte?

cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 - 6 mars 2007 à 10:21
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 - 10 mars 2007 à 18:48
bonjour,
je recherche des données dans une base de données
je ne recherche qu'une seule ligne
a partir de cette ligne je veux inserer une ligne dans une autre table

j'e donne ma methode mais elle ne me semble pas tres elegante et de tout emaniere elle ne marche pas...

sqlcommand cmd[...]
cmd.connection.open();
sqldatreader rdr=cmd.executereader();
while rdr.read()
{
    //test si un champ est different de 0
    if(rdr["chp1]  !=0)
    {
       cmd.commandtext=" insert .... nvel elem a partir de ce que je trouve ds chp 1"
       cmd.executenonquery();
    }
    if( rdr["chp2]  !=0)

    {

       cmd.commandtext=" insert .... nvel elem a partir de ce que je trouve ds chp 2"

       cmd.executenonquery();

    }
}
rdr.close();
cmd.connection.close();

j'obitens un message d'erreur lors de l'execution de cmd.executenonquery()
"there is already a datareader associated .... which must be closed first"

comment faire  pour faire les requetes que je desire (le plus rapidement et efficacement possible bien sur)

Merci

18 réponses

sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
6 mars 2007 à 10:32
il n'est pas possible d'utiliser plusieurs DbCommand (ou DbDataReader) en parallèles avec un DbConnection... en gros, il faut que tu ouvres autant de connections que d'opérations en parallèles... (attention aux perfs) 

Sébastien FERRAND (blog)
Consultant Indépendant
[Microsoft Visual C# MVP]
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 10:34
Salut,

En effet, il faut que tu ouvres une seconde connexion et donc instancier un second SqlCommand.
Pour faire ca proprement (au niveau fermeture de la connexion et libération des ressources) tu peux simplement utiliser un bloc using.

Par exemple :

<hr />using
(
SqlConnection connection1 =
new
SqlConnection())
{

   using (
SqlCommand cmd = connection1.CreateCommand())
   {
      connection1.Open();
      cmd.CommandText =
"TaRequete";

      SqlDataReader rdr = cmd.ExecuteReader();

      while (rdr.Read())
      {

         using (
SqlConnection connection2 =
new
SqlConnection())
         {
            connection2.Open();

            using (
SqlCommand cmd2 =
new
SqlCommand())
            {

               if (taCondition)
               {
                  cmd2.CommandText =
"Ta Requete";
                  cmd2.ExecuteNonQuery();
               }

               if (taCondition2)
               {
                  cmd2.CommandText =
"Ta Requete";
                  cmd2.ExecuteNonQuery();
               }
            }
         }
      }
   }
}
<hr />

Mx
MVP C# 
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 10:34
Oups, le temps de taper et mettre en forme... Ca faisait longtemps

Mx
MVP C# 
0
sebmafate Messages postés 4936 Date d'inscription lundi 17 février 2003 Statut Membre Dernière intervention 14 février 2014 37
6 mars 2007 à 10:36
hé hé

Sébastien FERRAND (blog)
Consultant Indépendant
[Microsoft Visual C# MVP]
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 10:37
Merci mais ya til un moyen efficace et rapide pour faire cela?
est ce la meilleure facon?
sachant ke je ne fait la recherche que d'une ligne....
merci
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 10:37
Mince, j'ai fait une betise avec l'instanciation de la seconde connexion dans la boucle du reader... Faudrait voir a la sortir de là

Mx
MVP C# 
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 10:41
Si tu fais la recherche que d'une ligne, tu auras ta clause WHERE dans ta requete, ton reader ne retournera qu'un ligne... Donc niveau perfs ca ne va pas etre une cata (et mon erreur citée juste au dessus n'a plus lieu d'etre ^^ )

Par contre tu peux ajouter tes requetes a la suite les unes des autres dans une string, et executer cette requete une bonne fois pour tout lorsque tu auras vérifié toutes tes conditions... A toi de voir ce qui t'arrange le plus.
Mx
MVP C# 
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 10:48
ok mais le truc c'est que ma condition depend des champs que je regarde avec mon select (ds le datareader)

et je sais pas faire  .... (je suis un peu nul en fait, si vou saviez pas remarqué lol)
pareil pour les requetes ala suite ds une meme string...
un exemple please...

en fait je fais un
select chp1,chp2 from table1
....
ds mon code je verifie si chp1>0
execute(insert (truc a partir de chp1) ds table2)
si chp2>0
execute(insert(truc a partir de chp2) ds table2)

evidemment je ne demande qu'a me perfectionner

si  vous avez des trucs pour ameliorer la rapidité et eprformance je usis preneur !!

en fait je ne sais faire que des trucs d ebase

Merci
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 11:03
Pour des requetes a la suite, c'est simple : tu utilises un StringBuilder et sa méthode Append pour y ajouter tes requetes.  (ou au pire tu concatenes des strings - seulement si tu as 2/3 requetes a ajouter). N'oublies pas de mettre des ';' entre chaque requete.
Et quand tu as passé toutes tes conditions, tu affectes la propriété CommandText de ton SqlCommand avec le contenu du StringBuilder, et tu appelles la méthode ExecuteNonQuery();

Mx
MVP C# 
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 11:46
ah d'accord "tout simplement"
et c bien plus rapide que de faire deux executenonquery a la suite ...? (2 fois plus rapide?)
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 11:47
et ya plus besoin de transaction si on met tout dans "une seule requete" ??
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
6 mars 2007 à 12:38
<hr />
Salut

Si tu n'as que 2 requetes a la suite, non tu n'auras pas un gros gain, mais bon, au moins le code est optimisé et plus lisible.
Par contre, si tu as besoin que cela soit fait dans une transaction alors tu n'en es pas exempté. (dans le cas présent, si la seconde requete plante, la premiere aura quand meme été effectuée).

Dans ce cas :

<hr />SqlTransaction t = connection2.BeginTransaction();

try
{
   cmd2.Transaction = t;
   cmd2.ExecuteNonQuery();
   t.Commit();
}

catch
{
   t.Rollback();
}

<hr />
Mx
MVP C# 
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 18:14
ok merci bien pour ces precisions je pense que cela va bien m'aider...

et alors comment tester des conditions a l'interieur meme d'uen requete?  est ce possible?
genre:
 insert truc_fait_a_partir_de_chp1 into table2  where chp1 in (select ch1 from table1 where truc_de_table1=laligne_que_je_cherche) [si chp1 !=0]

??

Merci
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
6 mars 2007 à 20:08
bon la g testé avec plusieurs insert a la suite mais g un souci...

ds une boulce je met des insert avec un decimal.tostring()
genre

string scmd="";
sqlcommand cmd=new ...
cdm.commandtext=scmd;
foreach datarow dr in dataset.tables[0].rows
{
scmd+=insert into table (article,montant) values( dr["article"].tostring(),dr["montant"].tostring())
}
cmd.executenonquery

mais j'ai un message d'erreur a cause de la virgule du champ montant : trop d eparametre (plus ds values que ds insert ...)

comment faire ?
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 mars 2007 à 08:39
Salut,

Excuse-moi j'ai pas pu venir te répondre depuis avant-hier.
Tu as avancé ou tu as toujours besoin d'aide ?

Mx
MVP C# 
0
cudenetf Messages postés 448 Date d'inscription mardi 20 septembre 2005 Statut Membre Dernière intervention 26 juillet 2012 2
8 mars 2007 à 08:59
ben j'ai fait un replace(",",".") ca semble marcher


merci en tt cas
0
MorpionMx Messages postés 3466 Date d'inscription lundi 16 octobre 2000 Statut Membre Dernière intervention 30 octobre 2008 57
8 mars 2007 à 09:06
Ok

Mx
MVP C# 
0
cs_coq Messages postés 6349 Date d'inscription samedi 1 juin 2002 Statut Membre Dernière intervention 2 août 2014 101
10 mars 2007 à 18:48
Salut,

Juste pour info, si le serveur est un SQL Server 2005 et qu'on travailles avec du .NET 2.0 mini, on peut probablement profiter de MARS (Multiple Active Result Sets).

/*
coq
MVP Visual C#
CoqBlog
*/
0
Rejoignez-nous