C# ADO.NET : Appel de procédures stockées et SqlDataReader
Appeler des procédures stockées SQL Server et lire les résultats en flux avec SqlDataReader, points clés :
SqlCommand.CommandType = CommandType.StoredProcedureindique l’exécution d’une procédure stockée- Passer les paramètres de la procédure stockée au moyen de
SqlParameter ExecuteReader(CommandBehavior.CloseConnection)pour lire le flux de données- SqlDataReader est un lecteur en lecture‑seule à sens unique, basé sur le flux ; il doit impérativement être fermé après utilisation
Définition de la procédure stockée
Vous devez d’abord créer la procédure stockée dans la base de données avant de pouvoir l’appeler.
create proc myProc
@id int
as
select * from [dbo].[Article] where id>@id
go
-- Test d'appel
exec myProc @id=5Langage du code : PHP (php)
Elle reçoit le paramètre @id et récupère les enregistrements de la table Article dont l’identifiant est supérieur à la valeur transmise.
Appeler une procédure stockée en C#
La méthode ExecuteReader renvoie un SqlDataReader qui permet de récupérer plusieurs enregistrements.
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
SqlCommand sqlCom = new SqlCommand();
sqlCom.Connection = conn;
sqlCom.CommandText = "myProc";
sqlCom.CommandType = CommandType.StoredProcedure;
SqlParameter param = new SqlParameter("@id", SqlDbType.Int, 8);
param.Value = 4;
param.Direction = ParameterDirection.Input;
sqlCom.Parameters.Add(param);
SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection);
StringBuilder sb = new StringBuilder();
while (reader.Read())
{
sb.AppendLine(reader[0] + "-" + reader[1]);
}
reader.Close();
MessageBox.Show(sb.ToString());
}Langage du code : C# (cs)
Libérer le Reader avec using pour éviter les fuites de ressources
string connectionString = "Data Source=.;Initial Catalog=db;Integrated Security=SSPI;";
using (SqlConnection conn = new SqlConnection(connectionString))
{
conn.Open();
using (SqlCommand sqlCom = new SqlCommand("myProc", conn))
{
sqlCom.CommandType = CommandType.StoredProcedure;//indique que la commande correspond à une procédure stockée
// ajouter le paramètre d'entrée
sqlCom.Parameters.Add("@id", SqlDbType.Int).Value = 4;
// CommandBehavior.CloseConnection : ferme automatiquement la connexion à la fermeture du reader
using (SqlDataReader reader = sqlCom.ExecuteReader(CommandBehavior.CloseConnection))
{
StringBuilder sb = new StringBuilder();
while (reader.Read())
{
// reader[0] première colonne, reader[1] deuxième colonne ; on peut aussi utiliser reader["NomColonne"]
sb.AppendLine($"{reader[0]}-{reader[1]}");
}
MessageBox.Show(sb.ToString());
}
// Pas besoin d’appeler manuellement reader.Close(), using assure la libération automatique
}
}Langage du code : C# (cs)
Les trois valeurs d’énumération CommandType
CommandType.Text: exécuter des instructions SQL classiquesCommandType.StoredProcedure: exécuter une procédure stockéeCommandType.TableDirect: lire directement une table de données
Si vous ne définissez pas
StoredProcedure, le programme interprète le nom de la procédure comme une instruction SQL ordinaire et génère une erreur !
Directions des paramètres SqlParameter
ParameterDirection.Input: paramètre d’entrée (transmission de valeurs, le plus utilisé)ParameterDirection.Output: paramètre de sortieParameterDirection.InputOutput: paramètre bidirectionnel entrée‑sortieParameterDirection.ReturnValue: valeur renvoyée par la procédure stockée
Fonction de CommandBehavior.CloseConnection
Lorsque SqlDataReader appelle Close() ou est libéré, il ferme automatiquement le SqlConnection associé.
Cas d’usage : quand une méthode renvoie un objet Reader, la connexion est récupérée automatiquement une fois que le code appelant a terminé la lecture.
Caractéristiques importantes de SqlDataReader
- Lecture‑seule à sens unique : on ne peut parcourir les lignes qu’avec
Read()vers le bas, pas de retour arrière ni de modification des données - Occupation de la connexion : tant que le Reader reste ouvert, la connexion à la base ne peut exécuter aucune autre opération
- Libération obligatoire des ressources : soit un appel manuel à
reader.Close(), soit préférer la libération automatique parusing - Deux manières de lire les colonnes :
csharp reader[0]; // lecture par index reader["Title"]; // lecture par nom de champ (meilleure lisibilité)
Points d’attention
- Oubli de définir
CommandType.StoredProcedure→ échec d’exécution - Incohérence sur la casse ou l’orthographe du nom du paramètre avec la procédure stockée → échec de correspondance des paramètres
- Reader non fermé : la connexion reste occupée, ce qui épuise le pool de connexions
- Exécuter une nouvelle requête base de données à l’intérieur de
while(reader.Read()): une même connexion ne peut pas hériter plusieurs Readers simultanément - Paramètres manquants ou types incompatibles dans la procédure stockée → erreur à l’exécution
Comparatif
| Méthode d’exécution | Cas d’usage | Objet renvoyé |
|---|---|---|
| ExecuteNonQuery | Procédures stockées d’insertion, mise à jour, suppression | int nombre de lignes affectées |
| ExecuteScalar | Retour d’une seule ligne et une seule colonne (requêtes d’agrégation) | object |
| ExecuteReader | Retour de jeux de données multi‑lignes | SqlDataReader (lecture en flux) |
SqlDataReader