Question

Quelle est la meilleure méthode pour transmettre des paramètres à SQLCommand? Vous pouvez faire:

cmd.Parameters.Add("@Name", SqlDbType.VarChar, 20).Value = "Bob";

ou

cmd.Parameters.Add("@Name", SqlDbType.VarChar).Value = "Bob";

ou

cmd.Parameters.Add("@Name").Value = "Bob";

Il semble que le premier puisse être en quelque sorte "meilleur" soit en termes de performance ou de vérification d'erreur. Mais je voudrais savoir plus définitivement.

Était-ce utile?

La solution

Vous pouvez également utiliser AddWithValue () , mais soyez conscient de la possibilité d'une conversion de type implicite erronée.

cmd.Parameters.AddWithValue("@Name", "Bob");

Autres conseils

Que se passe-t-il là-bas?

Vous citez les listes de paramètres pour plusieurs surcharges de Add . Ce sont des méthodes pratiques qui correspondent directement aux surcharges de constructeur de la classe SqlParameter . Ils construisent essentiellement l'objet paramètre en utilisant n'importe quel constructeur ayant la même signature que la méthode de confort que vous avez appelée, puis appellent SqlParameterCollection.Add (SqlParameter) comme suit:

SqlParameter foo = new SqlParameter(parameterName, dbType, size);
this.Add(foo);

AddWithValue est similaire mais prend encore plus de commodité, en définissant également la valeur. Cependant, il a en fait été introduit pour résoudre un problème de cadre. Pour citer MSDN,

  

La surcharge de Add qui prend une   chaîne et un objet a été déconseillé   en raison d'une ambiguïté possible avec le   surcharge SqlParameterCollection.Add   qui prend une chaîne et un SqlDbType   valeur d'énumération où passer un   entier avec la chaîne pourrait être   interprété comme étant le   valeur du paramètre ou le correspondant   Valeur SqlDbType . Utilisez AddWithValue   chaque fois que vous voulez ajouter un paramètre   en spécifiant son nom et sa valeur.

Les surcharges de constructeur pour la classe SqlParameter ne sont que commodités pour la définition des propriétés d'instance. Ils raccourcissent le code, avec un impact marginal sur les performances: le constructeur peut contourner les méthodes de définition et opérer directement sur des membres privés. S'il y a une différence, ce ne sera pas beaucoup.

Que dois-je faire?

Notez les éléments suivants (à partir de MSDN)

  

Pour bidirectionnel et sortie   les paramètres et les valeurs de retour, vous   doit définir la valeur de Taille . C'est   non requis pour les paramètres d'entrée, et   si elle n'est pas explicitement définie, la valeur est   déduit de la taille réelle de la   paramètre spécifié lorsqu'un   l'instruction paramétrée est exécutée.

Le type par défaut est input. Cependant, si vous autorisez la déduction de la taille de cette manière et recyclez l'objet paramètre dans une boucle (vous avez dit que vous vous intéressiez aux performances), la taille sera définie par la première valeur et les valeurs suivantes, plus longues, coupé. Évidemment, cela n’est significatif que pour les valeurs de longueur variable telles que les chaînes.

Si vous passez le même paramètre logique à plusieurs reprises dans une boucle, je vous recommande de créer un objet SqlParameter en dehors de la boucle et de le dimensionner correctement. Le surdimensionnement d'un varchar est inoffensif. Par conséquent, si vous souhaitez obtenir le maximum exact dans un PITA, définissez-le simplement plus grand que ce que vous attendez de la colonne. Étant donné que vous recyclez l'objet au lieu d'en créer un nouveau à chaque itération, la consommation de mémoire pendant la durée de la boucle risque de tomber , même si vous êtes un peu excité par le surdimensionnement.

À vrai dire, à moins que vous ne traitiez des milliers d'appels, rien de tout cela ne fera une grande différence. AddWithValue crée un nouvel objet, contournant le problème de dimensionnement. C'est court et doux et facile à comprendre. Si vous parcourez des milliers, utilisez mon approche. Sinon, utilisez AddWithValue pour que votre code reste simple et facile à gérer.

2008 était il y a longtemps

Depuis que j'ai écrit ceci, le monde a changé. Il y a de nouveaux types de dates, et il y a aussi un problème qui ne m’a pas traversé l’esprit jusqu’à ce qu’un problème récent lié aux dates me fasse penser aux conséquences de l’élargissement.

L'élargissement et le rétrécissement, pour ceux qui ne connaissent pas les termes, sont des qualités des conversions de types de données. Si vous affectez un int à un double, il n'y a pas de perte de précision car le double est "plus large". Il est toujours prudent de le faire, la conversion est donc automatique. C'est pourquoi vous pouvez affecter un int à un double, mais dans le sens contraire, vous devez effectuer une conversion explicite. Doubler en int est une conversion restrictive avec une perte de précision potentielle.

T

Je dirais n ° 1 à coup sûr. Toutefois, Microsoft le fait dans le bloc d’application d’accès aux données de la bibliothèque d’entreprise, ce qui est préférable, en particulier pour le serveur SQL:

http://msdn.microsoft.com/en-us/library /dd203144.aspx

J'avais l'habitude d'utiliser votre option 1:

  

cmd.Parameters.Add ("@ Name", SqlDbType.VarChar, 20) .Value = "Bob";

qui a bien fonctionné, mais j’ai commencé à utiliser .AddWithValue et c’est aussi simple que cela. Cela ne m'a pas posé de problème après plusieurs milliers d'utilisations. Remarquez, je passe presque toujours les variables privées de mes classes, je n'ai donc pas à m'inquiéter autant de la conversion de type implicite.

Cela dépend de votre application. En fait, j'aime bien 2, car je n'ai pas à changer mon DAO si je change la longueur d'un paramètre proc stocké. C'est juste moi si. Je ne sais pas s'il y a des pénalités de performance ou quoi que ce soit.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top