Bonjour à tous,
Je travaille sur un projet c# / SqlServer. J'ai crée des classes pour formaliser l'accès aux serveurs, la création de requêtes paramétrées, la gestion des exceptions pendant l'exécution des requêtes, etc...
le schéma est toujours le même : j'appelle une méthode avec en paramètres le nom du serveur, de la base, la requête en chaîne de caractères, et une liste de paramètres, celle ci effectue la requête et se charge de traitements spéciaux en cas d'exceptions.
Un exemple:
Cependant, mon programme utilise des requêtes préparées : je doit ouvrir une connexion, créer des paramètres, préparer la requête, et ensuite je rentre dans une boucle (pouvant contenant plusieurs dizaines d'itérations) et pour chaque itération j'exécute la requête après avoir renseigné la valeur des paramètres.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51 /// <summary> /// Exécute une requête d'écriture sur le serveur par défaut /// </summary> /// <param name="query">requête</param> /// <param name="prms">liste des paramètres</param> /// <exception cref="SqlException">exception levé en cas d'erreur SQL</exception> /// <exception cref="Exception">exception levé en cas d'erreur de connection (5 tentatives)</exception> /// <exception cref="Exception">exception levé, erreur inconnue</exception> public static void ExecQuery(string query, List<DbParam> prms) { int attemps = 0; while (attemps < 5) { using (IDbConnection c = DataProviderFactory.GetInstance().GetSqlConnection()) { try { c.Open(); IDbCommand cmd = c.CreateCommand(); cmd.CommandTimeout = 180; cmd.CommandText = query; AddParamsAndValues(cmd, prms); cmd.ExecuteNonQuery(); attemps = 5; } catch (SqlException e) { if (e.Number == 1 || e.Number == 17142) { if (attemps < 4) { attemps++; System.Threading.Thread.Sleep(10000); } else throw new ServerException("La connexion au serveur a échoué malgré 5 tentatives."); } else throw e; } catch { throw new Exception("Une erreur de type inconnue est survenue."); } } } }
Concrètement, cela donne un truc de ce genre :
J'aimerais remplacer ce code par celui ci ( que je trouve beaucoup plus beau
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30 using (SqlConnection c = DataProviderFactory.GetInstance().GetConnection()) { try { c.Open(); SqlCommand cmd = c.CreateCommand(); SqlCommand.commantText = "insert into Serveur.dbo.Table (id, nom, prix_public) values (@id, @nom, @value)"; // createParam est une méthode créant un paramètre pour l'objet Command CreateParam(cmd, "@id", DbType.Int32, 4); CreateParam(cmd, "@nom", DbType.String, 20); CreateParam(cmd, "@value", DbType.Decimal, 24, 6); cmd.Prepare(); // beaucoup de code sans rapport ici for(int i = 0; i < unTableauQuelconque.Count; i++) { // AddValue renseigne la valeur pour des paramètres déjà existants AddValue(cmd, "@id", unTableauQuelconque[i].["id"]); AddValue(cmd, "@nom", unTableauQuelconque[i].["nom"]); AddValue(cmd, "@value", unTableauQuelconque[i].["prix"]); cmd.ExecuteNonQuery(); } } catch (Exception e) { // gestion des exceptions } }):
Tout ça pour en venir à ma question : quel est le meilleur code ? Je n'arrive pas à le déterminer : je n'aime pas les requêtes préparés car ça m'oblige à utiliser une connexion persistante avec le serveur et que c'est plus contraignant à coder (réécriture de l'accès à la base, réécriture du traitement des exceptions, etc...) mais en contrepartie c'est A PRIORI plus rapide, mais la encore je ne connais pas la différence de perfs entre requêtes préparés et non préparés.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9 for(int i = 0; i < unTableauQuelconque.Count; i++) { List<DbParam> prms = new List<DbParam>(); prms.Add(new DbParam("@nom", DbType.String, 20, unTableauQuelconque[i].["nom"])); prms.Add(new DbParam("@id", DbType.Int32, 4, unTableauQuelconque[i].["id"])); prms.Add(new DbParam("@value", DbType.Decimal, 24, 6, unTableauQuelconque[i].["prix"])); ExecQuery("insert into Serveur.dbo.Table (id, nom, prix_public) values (@id, @nom, @value)", prms) }
Merci pour vos conseils.![]()
Partager