2010-01-15 5 views
1

J'ai besoin d'appeler une procédure stockée plusieurs fois, j'utilise informix. Je voudrais savoir si l'appel d'une procédure plusieurs fois avec la même connexion est le même en générant la chaîne avec les multiples appels à la procédure stockée et en l'exécutant comme une requête.Appel de plusieurs procédures stockées dans .net, comment le faire?

ceci est un exemple du code:

IfxCommand cmd = new IfxCommand("storeData", myconn); 
cmd.CommandType = CommandType.StoredProcedure; 
for (int i = 0; i < lbim; i++) 
{ 

    cmd.Parameters.Add("id", IBM.Data.Informix.IfxType.VarChar, 255).Value = info.id; 
    cmd.Parameters.Add("descripcionDescuentoImpuesto", IBM.Data.Informix.IfxType.VarChar, 255).Value = info.data[i].value; 
    try 
    { 
    IfxDataReader myreader = cmd.ExecuteReader(); 
    if (myreader.Read()) 
    { 
     Boolean aux = (Boolean)myreader[0]; 
     myreturn = aux; 
    } 
    myreader.Close(); 
    } 
    catch (IfxException ex) 
    { 
    } 
    cmd.Parameters.Clear(); 
} 

Le problème est que chaque procédure stockée renvoie true ou false.

Merci

+0

Ignorer les exceptions doit être quelque peu douteux, n'est-ce pas? –

+0

qu'est-ce que c'est? –

Répondre

2

Pour des raisons de performances, la meilleure approche consiste à préparer la commande avant la boucle. À l'intérieur de la boucle, vous pouvez définir les valeurs des paramètres et exécuter le lecteur. Je voudrais également améliorer le code avec 2 choses:

  • en utilisant des usines; De cette façon, vous pouvez facilement basculer entre OdbcDriver et IfxDriver ou quelque chose d'autre dans le futur; Erreur de manipulation: vous devez fermer le lecteur dans la section finally ou utiliser la clause "usings" qui garantit la libération des ressources en cas d'exception; Je préfère les utilisations car dans des scénarios plus complexes la section devient finalement très compliquée.

Cette modifications apporteraient le code suivant:

DbProviderFactory dbfactory; 
dbfactory = DbProviderFactories.GetFactory("IBM.Data.Informix"); 
using (myconn = dbfactory.CreateConnection()) 
{ 
    myconn.ConnectionString = " ... "; 
    myconn.Open(); 
    DbCommand cmd = dbfactory.CreateCommand(); 
    cmd.Connection = myconn; 
    cmd.CommandText = "storeData"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.Parameters.Clear(); 

    DbParameter parameter = dbfactory.CreateParameter(); 
    parameter.ParameterName = "id"; 
    parameter.DbType = DbType.String; 
    parameter.Size = 255; // probably not necessary 
    cmd.Parameters.Add(parameter); 

    parameter = dbfactory.CreateParameter(); 
    parameter.ParameterName = "descripcionDescuentoImpuesto"; 
    parameter.DbType = DbType.String; 
    parameter.Size = 255; 
    cmd.Parameters.Add(parameter); 

    cmd.Prepare(); 
    for (int i = 0; i < lbim; i++) 
    { 
     cmd.Parameters[0].Value = info.id; 
     cmd.Parameters[1].Value = info.data[i].value; 
     using (DbDataReader myreader = cmd.ExecuteReader()) { 
      if (myreader.Read()) 
      { 
       Boolean aux = (Boolean)myreader[0]; 
       myreturn = aux; 
      } 
     } 
    } 
} 
code

est maintenant beaucoup plus mais je pense que les avantages sont prépondérantes. Encore meilleure approche est d'utiliser Spring.NET (je l'apprends juste) - la moitié de la taille du code, conducteur indépendant (similaire à l'approche des usines), la disposition automatique des ressources en cas d'exception. Je voudrais aussi utiliser plutôt

myreturn = (bool)cmd.ExecuteScalar();

au lieu de lecteur de données. La chose suivante est que j'utilise plutôt le type de commande et "execute procedure storeData (?,?)". C'est à cause du bug d'Informix dans certains scénarios que j'ai depuis longtemps. Possible que cela est déjà fixé - donc il n'est probablement plus nécessaire.

1

Vous devez créer un nouvel objet IfxCommand pour chaque appel, donc il suffit de déplacer cette partie du code dans la boucle. En fait, c'est le cas, peu importe quel fournisseur vous utilisez.

+1

ce qui le rend meilleur? – sergiogx

+1

Pourquoi cela serait-il bénéfique? Je ne connais pas la sémantique exacte de l'opération .Add (si elle écrase les paramètres précédents pour le même nom de paramètre, alors tout va bien, sinon, il pourrait y avoir des problèmes). Mais en programmation SQL normale, préparer une déclaration une fois et l'exécuter plusieurs fois avec différents ensembles de paramètres est une bonne idée. –

+2

En fait, j'ai vérifié la documentation après avoir écrit ceci et il semble que vous puissiez réutiliser l'objet de commande, tant que les DataReaders de l'objet Command sont fermés. –

Questions connexes