2010-06-27 7 views

Répondre

5

Les paramètres SqlCommand ne peuvent être utilisés que pour transmettre des données. Vous ne pouvez pas les utiliser pour modifier l'instruction sql (par exemple ajouter des champs supplémentaires à une instruction select). Si vous avez besoin de modifier l'instruction sql, je suggère d'utiliser un StringBuilder pour créer l'instruction tsql.

Pour plus de détails, .Net ne concatène pas le sql avant de l'envoyer à SqlServer (du moins pas de la façon la plus simple possible). Il appelle réellement une procédure stockée et transmet les arguments séparément. Cela permet à Sql Server de mettre en cache le plan de requête et d'optimiser les performances de votre tsql.

Si vous deviez écrire ce SqlCommand ...

var cmd = new SqlCommand("SELECT * FROM MyTable WHERE MyID = @MyID", conn); 
cmd.Parameters.AddWithValue("@MyID", 1); 
cmd.ExecuteNonQuery(); 

C'est le tsql qui est délivré à Sql Server ...

exec sp_executesql N'SELECT * FROM MyTable WHERE MyID = @MyID',N'@MyID int',@MyID=1 

Vous pouvez en savoir plus sur sp_executesql on MSDN.

+0

Merci ... comme je l'ai su :) déjà fait un "trick" avec un String Builder, mais m'inquiète l'Injection SQL –

+0

Vous devriez toujours utiliser une SqlCommand avec des paramètres pour les valeurs. Si vous autorisez les utilisateurs à taper dans les champs, assurez-vous simplement que les noms de champs sont valides (au moins ne contiennent que des caractères valides) avant de les ajouter au sql. – Brian

10

Je suppose que vous essayez d'exécuter une instruction SQL comme

select @field from @table 

mais ça ne marchera pas. Sql ne peut pas avoir de paramètres sur les noms de champs ou de tables, seulement sur les valeurs.

Si ma réponse n'était pas correcte, veuillez prolonger votre question.

+0

Merci ... comme je l'ai su :) déjà fait un "trick" avec un String Builder, mais ça m'inquiète l'Injection SQL –

20

Si vous êtes préoccupé par l'injection SQL, la classe SqlCommandBuilder (et d'autres versions spécifiques de DB de DbCommandBuilder) dispose d'une fonction appelée QuoteIdentifier qui échappera correctement à votre nom de table.

var builder = new SqlCommandBuilder(); 
string escTableName = builder.QuoteIdentifier(tableName); 

Vous pouvez maintenant utiliser la valeur échappé lors de la construction de votre déclaration et ne pas avoir à se soucier, mais vous devriez par injection encore utiliser des paramètres pour toutes les valeurs.

Questions connexes