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 :

Tester l'existence d'un enregistrement avant insertion pour éviter les doublons


Sujet :

Développement SQL Server

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 37
    Points : 31
    Points
    31
    Par défaut Tester l'existence d'un enregistrement avant insertion pour éviter les doublons
    Bonjour,
    J'aimerais avoir votre avis sur la question suivante:
    Vaut-il mieux tester l'existence d'un enregistrement dans une table avant de l'insérer pour éviter les doublons ou bien réaliser l'insertion de l'enregistrement et laisser le SGBD ne pas l'insérer si doublon il y a?

    Par exemple j'ai une table 'Parametre' avec comme clé primaire le champ 'IDParam' et comme autre champ, un champ 'Valeur'.
    Je veux insérer des enregistrements que si ils n'existent pas déjà.
    Quel est le mieux:
    1) Faire un SELECT puis un INSERT si SELECT ne renvoi rien
    2) Faire un INSERT et ne pas traiter ni afficher l'erreur en cas de doublon

    Est-ce que les INSERT avec doublons vont écrire dans un log du SGBD qui finira par prendre du volume?
    Est-ce que la méthode (2) n'est pas correcte d'un point de vue programmation? Cette méthode permet d'écrire moins de code et de n'exécuter qu'une seule requête au lieu de deux
    Est-ce que la méthode (2) augmente le temps de traitement dans le cas ou un doublon existe?

    Merci par avance.

  2. #2
    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 : 42
    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,

    Il vous suffit de faire une demi-jointure pour ce faire, sur la clé technique ou naturelle.
    L'idéal est que la clé utilisée dans le prédicat de jointure soit indexée.

    Par exemple :

    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
    DECLARE @t TABLE
    (
    	i tinyint
    )
     
    INSERT INTO @t (i) VALUES (1), (2)
     
    ;WITH
    	CTE AS
    	(
    		SELECT	*
    		FROM	(
    				VALUES (0), (1), (2), (3)
    			) AS V(v)
    	)
    INSERT INTO @t
    (
    	i
    )
    SELECT		C.v
    FROM		CTE AS C
    LEFT JOIN	@t AS T ON C.v = T.i
    WHERE		T.i IS NULL
     
    SELECT	*
    FROM	@t
    @++

  3. #3
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Bonjour,

    Vous pouvez aussi utiliser la commande MERGE

  4. #4
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 37
    Points : 31
    Points
    31
    Par défaut
    Merci pour les réponses mais cela ne répond pas trop à mes questions.
    Peut-être me suis-je mal exprimé.
    Lors du démarrage d'un programme de gestion, je veux initialiser des valeurs par défaut dans ma base de donnée. Si les données existent, je ne veux pas les écraser.

    Par exemple dans une table 'parametre' avec comme clé primaire le champ 'IDParam' et comme autre champ, un champ 'Valeur'. Ce seront les 2 seuls champs de la table.

    Si je veux ajouter les valeurs ('param1','valeur1'), ('param2','valeur2'), ...
    Vaut-il mieux que j'écrive mon programme de la manière suivante:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    requete1 = "INSERT INTO parametre (idparam, valeur) VALUES ('param1','valeur1')
    ExecuteRequete requete1
    requete2 = "INSERT INTO parametre (idparam, valeur) VALUES ('param2','valeur2')
    ExecuteRequete requete2
    Et je ne traite pas les messages d'erreur en cas de doublon sur l'enregistrement

    ou bien

    requeteSelect1 = "SELECT count(*) FROM parametre WHERE idparam='Param1'"
    ExecuteRequete requeteSelect1
    Si le count(*) renvoie 0 ALORS
    RequeteInsert = "INSERT ...."
    FIN
    Idem avec l'enregistrement 2
    puis le parametre 3 etc...

  5. #5
    Modérateur

    Profil pro
    dba
    Inscrit en
    Janvier 2010
    Messages
    5 643
    Détails du profil
    Informations personnelles :
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : dba

    Informations forums :
    Inscription : Janvier 2010
    Messages : 5 643
    Points : 13 092
    Points
    13 092
    Par défaut
    Citation Envoyé par ggbbii Voir le message
    Merci pour les réponses mais cela ne répond pas trop à mes questions

    Bah si ! les deux solution permettront de n'insérer que si la données n'existe pas.
    L'avantage en plus par rapport a votre solution, c'est que vous pouvez mettre à jour la table en une seule fois plutôt que de faire autant de requete qu'il y a de lignes...

    EDIT :

    Pour le MERGE, en utilisant les données que vous venez de fournir, ça donnerait quelque chose comme ceci (pas testé) :


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    MERGE INTO parametre P
    USING ( VALUES 
                ('param1','valeur1')
                ,('param2','valeur2') 
    ) S(idparam, val)
        ON S.idparam= P.idparam
    WHEN NOT MATCHED BY TARGET THEN INSERT (idparam, valeur) VALUES(S.idparam, S.val)

  6. #6
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Février 2010
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2010
    Messages : 37
    Points : 31
    Points
    31
    Par défaut
    ok, merci, je vais essayer.

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

Discussions similaires

  1. Vérifier l'existence d'un enregistrement avant insertion
    Par patnership dans le forum Général Java
    Réponses: 5
    Dernier message: 19/02/2015, 13h05
  2. [MySQL] vérifier l'existance d'un enregistrement avant insertion
    Par patheoson dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 22/01/2010, 12h47
  3. Tester l'existence d'un enregistrement avant son ouverture
    Par Fredo67 dans le forum VBA Access
    Réponses: 2
    Dernier message: 28/01/2008, 17h15
  4. [MySQL] Vérification de la présence d'enregistrement avant insertion
    Par Odilon dans le forum PHP & Base de données
    Réponses: 7
    Dernier message: 28/09/2005, 15h30
  5. tester l'existance d'un enregistrement
    Par LoLoSS dans le forum Langage SQL
    Réponses: 5
    Dernier message: 07/05/2004, 14h58

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