Cedrix Posté(e) le 29 mars 2010 Partager Posté(e) le 29 mars 2010 Bonjour, Dans le cadre de mon stage, je développe une application à destination d'un service de la "boite". Je me retrouve confronté à un souci algorithmique par rapport au traitement d'un fichier importé depuis une autre application. C'est un fichier structuré qui comprend un lien vers l'identifiant d'une table dans une base de données. Plus concrètement, je dois donc vérifier dans ma base de données que cette clé existe bien dans la table de base... mais, imaginez un fichier de 14000 enregistrements (la table de base en comptant plus de 25000 elle-même), j'envisage donc plusieurs pistes : Lire le fichier entièrement. Vérifier (en mémoire et en base via un SELECT WHERE id = ? ..) pour chaque ligne l'existence de la clé associée. Mettre à jour une autre table avec les lignes correctes. ou Lire le fichier entièrement. Mettre à jour une autre table avec les lignes correctes via une procédure stockée qui vérifierait la condition. Il faut également savoir que je ne dois pas jeter les lignes incorrectes mais simplement les mettre dans un autre fichier (ou mettre à flag à 'faux', la solution n'a pas encore été choisie et dépendra probablement du traitement). Je pars du principe qu'un traitement local et en mémoire est plus performant qu'un traitement par accès disque (ligne par ligne) ou par le SGBD (passage par le réseau dans le cas d'une vérification ligne par ligne après lecture entière du fichier). Ma préférence se tourne vers la procédure stockée qui mettrait la table automatiquement à jour... Le fichier possède une en-tête de début et de fin de fichier dans lesquelles se trouvent un numéro de séquence (un même fichier ne devrait être importé qu'une seule fois, d'où permission de correction des erreurs). Outils de développement : - MS Visual Studio 2008 - MS SQL Server 2003 Merci d'avance pour vos réponses. Lien vers le commentaire Partager sur d’autres sites More sharing options...
uzak Posté(e) le 29 mars 2010 Partager Posté(e) le 29 mars 2010 T'as aussi la possibilité de te ramener les 25000 IDs de la table de référence. ça ne te fait plus que n+1 accès base au pire. C'est un traitement one-shot ? Si oui, la question des perfs ne se pose pas trop je pense Ta volumétrie n'est pas importante pour le moment, tu verras pas trop la différence entre toutes ces méthodes à mon avis Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cedrix Posté(e) le 31 mars 2010 Auteur Partager Posté(e) le 31 mars 2010 Merci de ta réponse, c'est bien un traitement "one shot" mais seulement au niveau des lignes (une seule ligne ne devrait être présente deux fois, chose non vérifiée - confiance au système qui l'envoie et dans les back up). J'ai procédé comme suit : - Lecture complète du fichier dans un tableau. - Récupération et vérification des entêtes. - Parsing des lignes. - Stockage en database via une procédure stockée qui vérifie si l'identifiant existe et qui met à vrai ou faux un booléen dans la table en conséquence. - Mise à jour du fichier de log. - Création d'un fichier d'erreur ayant la même structure (pour les longueurs de ligne - problème de parsing) et possibilité pour l'utilisateur de le réencoder. Le tout dans un BackGroundWorker avec délégués (pour ne pas figer l'interface et parce que j'ai plusieurs méthodes d'import/export à utiliser). Tout ceci fonctionne assez bien. J'ai préféré cette solution pour plusieurs raisons : - Une seule lecture sur le disque pour tout rapatrier. - Traitement en mémoire plus rapide que sur le disque. - Mise à jour des entêtes plus rapide (pas besoin de parcourir 2 fois le fichier en comptant le nombre de lignes). - Parsing en bloc des lignes intermédiaires et mise à jour d'une traite. Pas de risque de bug puisque j'ai "cassé" mes relations obligatoires. - Une seule consultation de la DB par la station. J'hésite maintenant à mettre un trigger sur la table plutôt que dans la procédure stockée. Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cedrix Posté(e) le 7 avril 2010 Auteur Partager Posté(e) le 7 avril 2010 C'est encore moi... J'importe maintenant un fichier .xls comprenant des contrats et des clients. Le tout est identifié par un numéro de châssis. Je travaille toujours en VB avec des DataAdapter. Mon souci, c'est que lors d'une importation, il se peut que je souhaite importer des contrats dont le châssis existe déjà, dans ce cas, la ligne devrait simplement être mise à jour (et il faudrait vérifier les nouvelles données car je dois détecter la modification, résiliation ou annulation d'un contrat). Je n'arrive pas à me trouver un algorithme performant. Le plus simple que j'aie trouvé est : - Charger tous les contrat déjà importés (ce qui peut devenir vite très lourd). - Importer les données dans un autre datatable. - Merge entre les 2 datatables et Update en base de données. Je travaille avec des procédures stockées. Auriez-vous une solution ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Shtong Posté(e) le 7 avril 2010 Partager Posté(e) le 7 avril 2010 Je verrais plutôt faire un adapter avec le selectcommand qui contient uniquement le contrat à modifier, et une updatecommand bien sûr. Comme ça tu charge juste le contrat à modifier et ensuite tu modifie directement la datarow et tu la sauvegarde. Note que tu modifie une ligne sur 1000 dans un dataset et que tu sauvegarde le dataset, il ne va enregistrer que ce qui a changé (et pas toutes les données sans distinction) ! Lien vers le commentaire Partager sur d’autres sites More sharing options...
Cedrix Posté(e) le 7 avril 2010 Auteur Partager Posté(e) le 7 avril 2010 Merci pour votre réponse. Le souci, c'est que je dois vérifier à chaque importation toutes les lignes du fichier (ce qui ferait 6000 lignes par fichier) et donc, 6000 accès à la BD. A long terme, ta solution devrait être plus rapide.. Maintenant, je me suis peut-être mal exprimé, je ne modifie rien. Les fichiers .xls arrivent depuis l'extérieur et doivent être importés dans le programme, ceux-ci contiennent quelques milliers de lignes. Sur ces quelques milliers de lignes, 2 cas sont possibles : - Soit c'est un nouveau contrat et alors, il doit être inséré dans la BD. - Soit c'est un contrat déjà existant et alors, il doit être mis à jour + positionner certains flags en fonction des champs mis à jour. Si je ne fais pas de merge par rapport à la BD existante, il va tenter d'insérer toutes les lignes. Situez-vous mieux le problème ? Lien vers le commentaire Partager sur d’autres sites More sharing options...
Messages recommandés
Archivé
Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.