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

Administration SQL Server Discussion :

Procédure stockée : gestion des doublons dans une table


Sujet :

Administration SQL Server

  1. #1
    Membre éclairé
    Inscrit en
    Mai 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 686
    Points : 716
    Points
    716
    Par défaut Procédure stockée : gestion des doublons dans une table
    Bonjour,

    Suite à un post datant d'il y a quelques temps (http://www.developpez.net/forums/d76...r-tables-vues/), j'ai mis en place une procédure stockée exécutée périodiquement via les plans de maintenance, me permettant de détecter un job fonctionnel en erreur.

    La procédure fait un contrôle sur deux tables et reprend la/les lignes qui remplissent certaines conditions. Ces lignes sont intégrées dans une table de travail, utilisée pour l'envoi par email.

    La procédure fonctionne très bien mais un cas nous remonte une erreur cad :
    Détection : OK (alerte + email : OK)
    Si aucune erreur : OK (pas d'alerte)
    Si erreur déjà renseignée dans la table de travail alors le plan de maintenance tombe en erreur : "Violation de la contrainte PRIMARY KEY 'PK__HLW000P__2E910F58'. Impossible d'insérer une clé en double dans l'objet 'reflex.hlw000p'"
    L'instruction a été arrêtée". Le problème c'est que les autres erreurs ne sont pas intégrés puisque détecté après l'entrée en double.
    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
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    SET ANSI_NULLS ON
    GO
    SET QUOTED_IDENTIFIER ON
    GO
     
    -- =============================================
    -- Author: Sébastien SAUMON et Christian SAUVIAT
    -- Create date: <04/02/09>
    -- Description:   Détection des receptions en erreur et envoi d'email à <a href="mailto:ssaumon@coopatl.lan">ssaumon@coopatl.lan</a>; 
    -- copie à <a href="mailto:csauviat@coopatl.lan">csauviat@coopatl.lan</a> et <a href="mailto:aperry@coopatl.lan">aperry@coopatl.lan</a> 
    -- =============================================
     
    ALTER PROCEDURE [dbo].[detection_reception_erreur2]
     
    -- =============================================
    -- SCRIPT EXECUTABLE EN ACTIVITE
    -- Create date: <04/02/09>
    -- Modification : < 17/06/09>
    -- Recherche dans les tables hlreclp et hlrecpp
    -- =============================================
     
    AS
    SET NOCOUNT ON
    -- =============================================
    -- Déclaration des variables
    DECLARE @T TABLE (wekobj VARCHAR(256))
    DECLARE @wekobjs VARCHAR(max)
    DECLARE @dbname VarChar (30)
    DECLARE @Err VARCHAR(256)
    DECLARE @Cpt Int
     
    -- SET @dbname = 'RFXCOOPPROD'
     
    -- insertion des erreurs (?)
    INSERT INTO reflex.hlw000p (hlcssn, WENRGP, wekobj) 
    OUTPUT inserted.wekobj INTO @T
    SELECT 'RECDEBUG', '1', r1cact + ' ' + r1cdpo + ' ' + CAST(r1nann AS varchar(32)) + ' ' + CAST(r1nrec AS varchar(32)) + ' ' + CAST(r1nlir AS varchar(32))
    FROM   reflex.hlreclp
           INNER JOIN reflex.hlrecpp
                 ON     recact = r1cact 
                    AND recdpo = r1cdpo 
                    AND renann = r1nann 
                    AND renrec = r1nrec
    WHERE r1nann = 5
      AND R1QBVR = 0
      AND retmev = 1
      AND RETRVA = 0;
     
     
    -- concaténation des erreurs pour envoi d'un mail
    SET @wekobjs = '';
    SELECT @wekobjs = @wekobjs + wekobj +'<br>'
    FROM   @T
    WHERE  NOT EXISTS(SELECT * 
                     FROM   reflex.hlw000p 
                     WHERE  hlcssn = 'RECDEBUG' 
                       AND  wekobj=@Err)
     
    IF ISNULL(@wekobjs, '') <> ''
    BEGIN
    EXEC msdb.dbo.sp_send_dbmail @recipients='xx@coopatl.lan',
    							 @copy_recipients='xxx@coopatl.lan;xxx@coopatl.lan',
                                 @subject = 'Reception PRD en erreur',
                                 @body = @wekobjs,
                                 @body_format = 'HTML';
     
    END

  2. #2
    Membre actif
    Inscrit en
    Février 2009
    Messages
    224
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 224
    Points : 269
    Points
    269
    Par défaut
    Bonjour,
    Il est necessaire de mettre votre insert dans un try/catch ainsi en cas d'erreur sur l'insert, l'erreur sera propagé vers le bloc catch.
    Par exemple pour la table:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    create table suivi (
    	id int constraint pk_suivi primary key,
    	info nvarchar(80)
    );
    il est possible d'exécuter n fois le bloc suivant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    begin try
    	insert into suivi values(1,'blabla');
    end try
    begin catch
     
    end catch;

  3. #3
    Membre éclairé
    Inscrit en
    Mai 2008
    Messages
    686
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 686
    Points : 716
    Points
    716
    Par défaut
    Le fait d'utiliser cette commande permettrait elle lors d'une insertion de deux lignes de passer outre la première qui tombe en erreur et d'insérer la seconde dans la table de travail ?

    Ou s'agit t'il juste de vérifier le plan et de récupérer les erreurs ?

  4. #4
    Membre actif
    Inscrit en
    Février 2009
    Messages
    224
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 224
    Points : 269
    Points
    269
    Par défaut
    Dans votre procédure initiale les données de l'insert proviennent du SELECT et donc plusieurs lignes . Si une ligne pose soucis alors c'est l'intégralité de L'INSERT qui tombe en échec (comportement normal transactionnel).
    Donc dans votre cas 2 possibilités s'offrent à vous:
    - Soit modifier votre code pour que chaque INSERT porte sur une ligne (donc faire une boucle)
    - Soit nettoyer votre table cible avant d'ajouter les données
    - Soit modifier la clé primaire de votre table pour éviter les doublons

  5. #5
    Expert éminent sénior
    Avatar de mikedavem
    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Août 2005
    Messages
    5 450
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : Distribution

    Informations forums :
    Inscription : Août 2005
    Messages : 5 450
    Points : 12 891
    Points
    12 891
    Par défaut
    Bonjour,

    Une autre piste (complémentaire) serait d'utiliser SSIS et le composant Lookup qui répondrait à votre problème.

    ++

Discussions similaires

  1. Réponses: 1
    Dernier message: 04/08/2011, 10h48
  2. Requête pour supprimer des doublons dans une table
    Par nomade333 dans le forum Contribuez
    Réponses: 0
    Dernier message: 30/03/2008, 12h48
  3. Obtenir la liste des doublons dans une table SAS
    Par marie mouse dans le forum SAS Base
    Réponses: 2
    Dernier message: 05/12/2007, 15h33
  4. Gestion des images dans une table en OLE
    Par Ale74 dans le forum IHM
    Réponses: 9
    Dernier message: 22/03/2007, 14h55
  5. Eliminer des Doublon dans une Table
    Par Soulama dans le forum MS SQL Server
    Réponses: 5
    Dernier message: 03/02/2005, 14h27

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