IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Développement SQL Server Discussion :

Besoin de conseil pour loguer les résultats des requetes


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut Besoin de conseil pour loguer les résultats des requetes
    Bonjour,
    on me demande de loguer le résultat d'une requête, afin de savoir quels enregistrements posent problèmes, sachant que les requêtes vont insérer des tables entières ( et je suis sous sql 2005).

    Basiquement ma requête était:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	INSERT afm.bl(bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon)
    	SELECT bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon
    	FROM afm.afm1_bl
    	WHERE afm.afm1_bl.bl_id NOT IN (SELECT bl_id FROM afm.bl )
    (J'insère dans la nouvelle table, tout ce qui n'existe pas déjà).
    Ensuite on me demande de loguer les erreurs dans une autre table..
    Et la j'ai l'impression que je suis tombé dans une usine et je sais pas si j'ai trouvé une bonne solution(même si ca semble bien marcher).
    Pouvez-vous me conseiller ?



    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
    CREATE PROCEDURE afm.afm1_insert_all
    AS
     
    DECLARE
    @myBLID varchar(50);
     
    DECLARE myCursor CURSOR FOR
    SELECT bl_id
    			FROM afm.afm1_bl order by bl_id
    			WHERE afm.afm1_bl.bl_id NOT IN (SELECT bl_id FROM afm.bl );
     
    OPEN myCursor;
    FETCH NEXT FROM myCursor
    into @myBLID;
     
     
     
    insert_block:
    BEGIN TRY
    	WHILE @@FETCH_STATUS= 0 
    	BEGIN
    		INSERT INTO afm.bl (bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon)
    		SELECT bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon
    		FROM afm.afm1_bl
    		WHERE afm.afm1_bl.bl_id = @myBLID
     
    		FETCH NEXT FROM myCursor
    		into @myBLID;
    	END
     
    END TRY
    BEGIN CATCH
    	select        
    		ERROR_NUMBER() AS ErrorNumber,
            ERROR_SEVERITY() AS ErrorSeverity,
            ERROR_STATE() AS ErrorState,
            ERROR_PROCEDURE() AS ErrorProcedure,
            ERROR_MESSAGE() AS ErrorMessage,
    		@myBLID as bl_id;	
    		FETCH NEXT FROM myCursor
    		into @myBLID;
    		GOTO insert_block	
    END CATCH
     
    CLOSE myCursor
    DEALLOCATE  myCursor
    J'ai pas encore fais le traitement dans le "catch" mais je vais insérer les infos que j'affiche là dans une autre table.


    Donc une grosse procédure pour :
    - voir l'enregistrement qui pose souci (la clé primaie = bl_id)
    - une fois l'erreur levée, continuer le traîtement avec les autres enregistrements.

    Estce que mon raisonnement est juste ?
    Est-ce qu'on peut mieux faire et plus simplement ? J'ai pas mal de tables à faire selon ce principe, et ce n'est que les Inserts..

    Au départ je voulais faire une procédure "insert" avec toutes mes requêtes d'insertions et avoir un TRY/Catch pour tout qui me remontrerai l'erreur, la table concernée et l'enregistrement (mais là je suis paumé).

  2. #2
    Expert confirmé
    Avatar de rudib
    Homme Profil pro
    Fakir SQL Server & NoSQL
    Inscrit en
    Mai 2006
    Messages
    2 573
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Fakir SQL Server & NoSQL

    Informations forums :
    Inscription : Mai 2006
    Messages : 2 573
    Points : 4 043
    Points
    4 043
    Par défaut
    Bonjour,

    ton fonctionnement n'est pas idéal, les curseurs sont très contre-performants.

    pourquoi ne pas identifier avant insertion les lignes qui vont provoquer des erreurs (par exemple, une clé étrangère qui n'a pas de référence dans une table-mère), et mettre ces lignes dans une table d'audit, en un seul INSERT, puis insérer les autres lignes, en une seule instruction, dans la bonne table ?

  3. #3
    Membre averti
    Homme Profil pro
    R&D
    Inscrit en
    Avril 2004
    Messages
    127
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : R&D

    Informations forums :
    Inscription : Avril 2004
    Messages : 127
    Points : 406
    Points
    406
    Par défaut
    Citation Envoyé par Fritzoune Voir le message
    Bonjour,
    on me demande de loguer le résultat d'une requête, afin de savoir quels enregistrements posent problèmes, sachant que les requêtes vont insérer des tables entières ( et je suis sous sql 2005).

    Basiquement ma requête était:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    	INSERT afm.bl(bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon)
    	SELECT bl_id,name,site_id,cost_sqft,dwgname,ehandle,lat,lon
    	FROM afm.afm1_bl
    	WHERE afm.afm1_bl.bl_id NOT IN (SELECT bl_id FROM afm.bl )
    (J'insère dans la nouvelle table, tout ce qui n'existe pas déjà).
    Ensuite on me demande de loguer les erreurs dans une autre table..
    Et la j'ai l'impression que je suis tombé dans une usine et je sais pas si j'ai trouvé une bonne solution(même si ca semble bien marcher).
    Pouvez-vous me conseiller ?
    Crée le trigger INSTEAD OF sur cette table qui fait le traitement en déplaçant les lignes incorrectes detectées dans une autre table.

  4. #4
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut
    Ah ouais ca à l'air pas mal
    Merci.
    Je testerai ca sur le prochain projet
    Les curseurs ont été acceptés et j'arrive a 15mn de traitements pour toute ma base, c'est pas trop dérangeant dans ce que j'ai du faire là.

  5. #5
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    Bonjour,

    Quelque soit l'utilisation que vous faites de votre base de données, surtout si elle est faible, 15 minutes est tout simplement inacceptable.

    Avec une vraie requête SQL, le même traitement prendrait peut-être quelques secondes, comme je l'ai démontré ici .
    A vous de voir si vous préférez faire dans la quantité de lignes de codes ou dans leur qualité ...

    Ainsi votre INSERT peut directement s'écrire :

    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
    INSERT	INTO afm.bl
    (
    	bl_id
    	, name
    	, site_id
    	, cost_sqft
    	, dwgname
    	, ehandle
    	, lat
    	, lon
    )
    SELECT		AFM1_B1.bl_id
    		, AFM1_B1.name
    		, AFM1_B1.site_id
    		, AFM1_B1.cost_sqft
    		, AFM1_B1.dwgname
    		, AFM1_B1.ehandle
    		, AFM1_B1.lat
    		, AFM1_B1.lon
    FROM		afm.afm1_bl AS AFM1_B1
    LEFT JOIN	afm.bl AS B1 ON AFM1_B1.bl_id = B1.bl_id
    WHERE		B1.bl_id IS NULL
    Et la transaction sera totalement annulée si une seule erreur est rencontrée.
    Il faut donc partir du libellé de l'erreur (que vous ne donnez pas) et rechercher ce qui en est la cause dans vos données.

    @++

  6. #6
    Membre du Club
    Profil pro
    Inscrit en
    Mars 2003
    Messages
    98
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2003
    Messages : 98
    Points : 61
    Points
    61
    Par défaut
    Alors je suis entièrement d'accord avec vous,
    sauf que:
    je ne suis absolument pas un spécialiste SQL (et c'est pas faute de leur dire que c'est pas mon job..) et que les contraintes business l'emportent sur la qualité de ce script (vu que je ne maitrise pas vraiment le sujet, les heures passées à optimiser le script vont coûter bien plus cher que les 15mn (au lieu de 3) de traîtements à 2h du matin).
    Et que ledit client est tout simplement insupportable, je souffre déjà assez comme ça

    Ensuite votre requête ne permet pas de logguer l'enregistrement fautif.
    Est-ce qu'avec le trigger instead of de Serguei; ca fonctionnerait ?

    Le type d'erreur que je rencontre c'est soit des données trop grandes par rapport au champs d'arrivée, soit des contraintes d'intégrités ( clefs étrangères ) qui ne sont pas vérifées ou d'autres que je peux pas savoir avant de tenter de les importer.
    Ou alors, avant de faire l'insert, il faudrait que je test chaque champ d'import s'il correspond à l'arrivée. Mais ca devient un travail de fourmi, qui n'était pas prévu dans le scope du projet à l'origine :S

    Dur dur de devoir réaliser un projet quand la charte est pas bien définie par le commanditaire et que je suis pas spécialisé

  7. #7
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Points : 12 371
    Points
    12 371
    Par défaut
    je ne suis absolument pas un spécialiste SQL (et c'est pas faute de leur dire que c'est pas mon job..) et que les contraintes business l'emportent sur la qualité de ce script (vu que je ne maitrise pas vraiment le sujet, les heures passées à optimiser le script vont coûter bien plus cher que les 15mn (au lieu de 3) de traîtements à 2h du matin).
    Et que ledit client est tout simplement insupportable, je souffre déjà assez comme ça
    Je peux le comprendre, j'ai été dans cette situation deux fois.
    Donc j'ai démissionné deux fois, parce que je n'aime pas faire de la merde, et que souvent ne pas en faire, ce n'est pas aussi compliqué qu'on le croit.
    Je ne vous blâme pas, je tire au boulet sur la vision à très court terme de la gestion du personnel et de sa formation par les entreprises IT de France.
    C'est-à-dire que le coût de votre formation est bien moins cher que la source d'ennuis vers laquelle votre entreprise et ses clients se dirigent.

    Ensuite votre requête ne permet pas de logguer l'enregistrement fautif.
    Est-ce qu'avec le trigger instead of de Serguei; ca fonctionnerait ?
    La solution de Serguei pourrait tout à fait fonctionner, mais elle ne vous exempt pas :

    - d'utiliser mon exemple de code plutôt qu'un curseur,
    - des erreurs à l'insertion

    c'est soit des données trop grandes par rapport au champs d'arrivée, soit des contraintes d'intégrités ( clefs étrangères ) qui ne sont pas vérifées
    C'est détectable en amont en deux requêtes

    Ou alors, avant de faire l'insert, il faudrait que je test chaque champ d'import s'il correspond à l'arrivée. Mais ca devient un travail de fourmi, qui n'était pas prévu dans le scope du projet à l'origine :S
    Je suis d'accord avec vous et ce sera très lent à faire en base de données.
    Abandonnez tout simplement l'idée

    Dur dur de devoir réaliser un projet quand la charte est pas bien définie par le commanditaire et que je suis pas spécialisé
    Repensez à ce que j'ai écrit plus haut ... Je sais que le contexte actuel ne s'y prête pas.
    Cela peut prendre du temps de changer d'entreprise, mais considérez aussi ce que cela peut apporter à votre carrière

    @++

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Réponses: 4
    Dernier message: 21/04/2015, 13h27
  2. Réponses: 2
    Dernier message: 13/02/2015, 20h30
  3. [CppUnit / ECUT] Pb pour voir les résultat des tests
    Par noisy_man dans le forum Eclipse C & C++
    Réponses: 2
    Dernier message: 09/08/2011, 18h56
  4. Besoin de conseil pour choisir les technologies de mon futur projet
    Par cryosore dans le forum Langages de programmation
    Réponses: 1
    Dernier message: 26/04/2009, 10h58
  5. [MySQL] 1 seul tableau pour tous les résultats de requetes
    Par oceane751 dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 25/05/2006, 20h12

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo