Comment faire une requête paramétrée dans une base de données

Préambule

Après avoir vu une quantité impressionnante de question sur ce forum comportant des requêtes SQL écrite sans paramètres, je me suis enfin décidé à écrire un petit tutoriel à ce sujet.

Pourquoi utiliser des requêtes paramétrées ?

Eh oui, certains me diront, "mais j'ai jamais fait comme ça, et ça fonctionne très bien".

Alors qu'ils font des requêtes du style :

String sql = "INSERT INTO TableTest(Id, Text, DateAndTime, FloatNumber) VALUES(" + id.ToString() + ",'" + text + "'," + DateTime.Now.ToString() + "," + floatNum.ToString() + ")";

Mais il faut connaître les risque de telles requêtes, je vais essayer d'en résumé quelques-uns ci-dessous :

Problèmes de régionalisation

Les dates, comme les nombres à virgule, peuvent avoir des formats différents suivant les régions. Une requête peut très bien fonctionner sur un environnement de développement, et plus chez un client.

DateTime.Now.Tostring() ne donnera pas forcément un format de date valide pour la base de données, ou peut inverser les jours et les mois. Bonjour la maintenance pour démêler tout ça !

Problèmes de texte

Un texte mis dans une requête SQL doit être entouré du caractère '. Si le texte à insérer en contient aussi, il ne faut pas oublier de remplacer tout ' par des doubles '', pour que le SQL fonctionne.

Dans l'exemple ci-dessus, si la variable text contient des ', la requête va échouer.

Ca peut paraître insignifiant, mais ça peut aussi être la source de trous de sécurité. (cf Injection SQL)

Comment faire juste ?

Le code ci-dessous donne un petit exemple de requête paramétrée. Il s'appuie sur une table de 4 colonnes (Id int, text varchar(50), DateAndTime DateTime, FloatNumber float), et y insère une ligne.

using (SqlConnection conn = new SqlConnection(connectionString))
{
    //Préparation des paramètres
    SqlParameter paramID = new SqlParameter("@id", SqlDbType.Int);
    paramID.Value = 10;
    SqlParameter paramText = new SqlParameter("@text", SqlDbType.VarChar,50);
    paramText.Value = "Ceci est un test";
    SqlParameter paramDate = new SqlParameter("@date", SqlDbType.DateTime);
    paramDate.Value = DateTime.Now;
    SqlParameter paramFloat = new SqlParameter("@float", SqlDbType.Float);
    paramFloat.Value = 12.2;

    //Préparation de la commande
    String sql = string.Format("INSERT INTO TableTest(Id, Text, DateAndTime, FloatNumber) VALUES({0},{1},{2},{3})",
    paramID.ParameterName, paramText.ParameterName,
    paramDate.ParameterName, paramFloat.ParameterName);
    SqlCommand cmd = new SqlCommand(sql.ToString(), conn);

    //Ajout des paramètre à la commande
    cmd.Parameters.Add(paramID);
    cmd.Parameters.Add(paramText);
    cmd.Parameters.Add(paramDate);
    cmd.Parameters.Add(paramFloat);

    //Ouverture de la connection et exécution de la commande
    conn.Open();
    cmd.ExecuteNonQuery();
}

Bien sur, ces paramètres peuvent aussi être utilisés pour des UPDATE, SELECT ou DELETE, dans la clause WHERE ou ailleurs dans la requête.

J'espère que ce mini tutorial vous aidera, et n'hésitez pas à me faire vos commentaires.

Amicalement,

Sharpmao

A voir également
Ce document intitulé « Comment faire une requête paramétrée dans une base de données » issu de CodeS SourceS (codes-sources.commentcamarche.net) est mis à disposition sous les termes de la licence Creative Commons. Vous pouvez copier, modifier des copies de cette page, dans les conditions fixées par la licence, tant que cette note apparaît clairement.