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

MS SQL Server Discussion :

Verifier la présence d'un enregistrement


Sujet :

MS SQL Server

  1. #1
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut Verifier la présence d'un enregistrement
    Bonjour,

    Ma table TEMP dans laquelle il y a toutes les informations récupérée de mon fichier source.
    Il y a notamment toutes les entreprises identifiées par un ID (Id_temp), jusqu'a présent afin de créer ma dimension ENTREPRISES dans mon modèle de BDD je faisais :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    INSERT INTO ENTREPRISES 
    ( 
    	  Siren 
    	, Raison_Sociale 
    	, Adresse 
    ) 
    SELECT	DISTINCT  		T.Siren 
    				, T.Raison_Sociale 
    				, T.Adresse 
    FROM		TEMP AS T 
    LEFT JOIN	ENTREPRISES AS E 
    		ON T.Siren = E.Siren 
    WHERE		E.Siren IS NULL
    Le problème c'est qu'au début de la création de ma Dimension ENTREPRISE ça ne me posait pas de problème sauf que maintenant je dois faire face à l'arrivé de nouvelles entreprises à partir de nouveaux fichiers plats...
    Donc je voudrais pouvoir vérifier si l'entreprise existe déjà ou non et l'insérer si elle n'y est pas.
    Car avec mon INSERT juste au dessus, dès que je veux faire une modification cela pose problème car ma table ENTREPRISES est rattachée par un FK sur ma table des faits !

    Pourriez vous me donner un coup de main, des pistes ?

    Merci

  2. #2
    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 piste : l'instruction MERGE si vous êtes en SQL Server 2008

    ++

  3. #3
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Merci @mikedavem, c'est parfait

  4. #4
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Bon j'ai parlé un peu trop vite... Enfin je suis en train de galéré pour avec le MERGE :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MERGE INTO ENTREPRISES E
    USING (SELECT Id_Temp, Siren, Raison_Sociale, Adresse, Ville, Cp FROM TEMP) T
        ON ( E.Siren = T.Siren AND E.Siren IS NULL) -- Condition de correspondance
    WHEN MATCHED THEN -- Si Vraie
      UPDATE SET E.Siren = T.Siren
    WHEN NOT MATCHED THEN -- Si faux
      INSERT (E.Siren, E.Raison_Sociale, E.Adresse, E.Ville, E.Cp) VALUES (T.Siren, T.Raison_Sociale, T.Adresse, T.Ville, T.Cp)
    J'ai cette erreur qui est retournée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    La liste d'insertion de colonne utilisée dans l'instruction MERGE ne peut pas contenir d'identificateurs en plusieurs parties. Utilisez à la place des identificateurs en une partie.

    J'arrive pas a comprendre, si je veux actualiser que l'adresse d'un entreprise si elle a changé entre deux fichiers plats, ou si je veux rajouter une entreprise si elle n'était pas déjà enregistrée, c'est dans qu'elle partie du MERGE que je dois le definir ?

    EDIT 1 :

    Je rajoute un petit schéma pour mieux comprendre ce que je veux faire en PJ
    Images attachées Images attachées  

  5. #5
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Gironde (Aquitaine)

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

    Informations forums :
    Inscription : Novembre 2004
    Messages : 1 795
    Points : 3 173
    Points
    3 173
    Par défaut
    ya pas un soucis la?
    Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
    MCTS Database Development
    MCTS Database Administration

  6. #6
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Non le soucis vient de l'INSERT car quand j'enlève la partie :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    WHEN NOT MATCHED THEN -- Si faux
      INSERT (E.Siren, E.Raison_Sociale, E.Adresse, E.Ville, E.Cp) VALUES (T.Siren, T.Raison_Sociale, T.Adresse, T.Ville, T.Cp)
    La requête s’exécute sans erreur...

  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 : 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,

    Je suis d'accord avec iberserk

    Pour ma part je ne suis pas un grand fan de MERGE ...
    Faites donc :

    - un UPDATE avec un INNER JOIN entre les deux tables
    - un INSERT avec un LEFT JOIN, la table à gauche de la jointure étant la table TEMP, en testant WHERE E.Siren IS NULL

    @++

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Faites donc :

    - un UPDATE avec un INNER JOIN entre les deux tables
    - un INSERT avec un LEFT JOIN, la table à gauche de la jointure étant la table TEMP, en testant WHERE E.Siren IS NULL

    @++
    Sans vouloir paraitre débile...
    Je fais chaque requête l'une après l'autre ou je fais un IF EXISTS UPDATE... ELSE INSERT ?

    Je me permet de mettre les deux requetes que j'ai fait du coup pour le moment :

    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
    UPDATE	ENTREPRISES
    SET		Siren = T.Siren, Raison_Sociale=T.Raison_Sociale, Adresse=T.Adresse, Ville=T.Ville, Cp=T.Cp
    FROM	ENTREPRISES AS E
    INNER JOIN TEMP AS T
    ON		E.Siren = T.Siren
    INSERT	ENTREPRISES
    (
    	Siren
    	, Raison_Sociale
    	, Adresse
    	, Ville
    	, Cp
    )
    SELECT		DISTINCT T.Siren
    		, T.Raison_Sociale
    		, T.Adresse
    		, T.Ville
    		, T.Cp
    FROM		BDD_INCIDENTS.dbo.TEMP AS T
    LEFT JOIN	        ENTREPRISES AS E
    			ON T.Siren = E.Siren
    WHERE		E.Siren IS NULL
    EDIT : Bon si j'ai bien compris, au départ je fais un INSERT à partir de ma table TEMP qui contient l'extraction des mes fichiers sources, donc à partir de ce moment j'ai toutes mes Entreprises qui sont insérées dans ma table ENTREPRISES sans doublon.

    Ensuite si je rajoute un nouveau fichier avec des nouvelles données qui s'insère dans TEMP, lorsque je fais l'UPDATE il y a un problème avec les numéros de Siren à '000000000' (c'est les entreprises n'ayant pas de Siren car elles sont à l'étranger).
    En effet je me retrouve à avoir une mise a jour de chaque champs (Raison_Sociale, Adresse, Ville et Cp) mais à partir du même Siren.

    Exemple :
    Au début avec l'INSERT :

    Id_entreprise; Siren; Raison_Sociale; Adresse, Ville, Cp
    1; '000000000'; ENTREPRISE1; 2 rue Bidule, Venise, 0
    2; '000000000'; ENTREPRISE2; 54 rue Machin, Prague, 0

    Après avec l'UPDATE :
    Id_entreprise; Siren; Raison_Sociale; Adresse, Ville, Cp
    1; '000000000'; ENTREPRISE1; 2 rue Bidule, Venise, 0
    2; '000000000'; ENTREPRISE1; 2 rue Bidule, Venise, 0
    3; '000000000'; ENTREPRISE1; 2 rue Bidule, Venise, 0
    ... et ca sur toutes les Siren à '000000000'

  9. #9
    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
    Personne n'est débile, et on ne peut pas reprocher à des gens de ne pas savoir.
    En revanche on peut leur reprocher de ne pas chercher, mais ce n'est pas votre cas

    le IF EXISTS sur un UPDATE est inutile, puisque vous le faites avec un INNER JOIN.
    Donc il ne fonctionnera que pour les lignes dont la colonne qui participe au prédicat de jointure est vérifié.
    Les autres ne seront pas touchées.

    Donc vous pouvez exécuter les deux requêtes à la suite sans souci.
    En revanche, vous voudrez peut-être les encapsuler dans une transaction explicite :

    - BEGIN TRANSACTION maTransaction
    - UPDATE ...
    - INSERT ...
    - test de l'INSERT
    - Si le test est bon : COMMIT TRANSACTION maTransaction
    - Si le test n'est pas bon : ROLLBACK TRANSACTION maTransaction

    de cette façon c'est tout ou rien

    En ce qui concerne les entreprises qui n'ont pas de SIREN, ou plutôt qui ont un SIREN à 00000000, il va falloir les traiter séparément.
    Vous pouvez par exemple les marquer à NULL et filtrer l'UPDATE sur les SIREN qui ne sont pas NULL; idem pour l'INSERT.
    Pour ceux qui sont à NULL, je ne sais pas comment vous vérifiez s'ils sont déjà dans votre table cible (UPDATE) ou s'il faut les ajouter (INSERT).

    @++

  10. #10
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Merci pour les bon conseils encore une fois !

    Concernant mon histoire des SIREN à 0 je ne comprend pas bien car lorsque que je fais l'INSERT il arrive très bien à faire la distinction sur les SIREN à 0, à savoir un enregistrement différent pour un même SIREN surement grâce aux autres champs...

    Enfin bon je vais continuer à chercher et je reviendrais surement pour vous faire part de l'avancement !

    Merci encore, je file faire des tests

  11. #11
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Bon finalement, je m'apercois que j'ai besoin de faire la même chose entre ma table de faits et mes dimensions...

    A savoir je voudrais mettre à jour si il y a des valeurs qui ont été modifiées ou rajouter les lignes lorsqu'il y a des nouveaux enregistrements dans ma table TEMP

    J'ai fait le code suivant sous vos conseils mais a chaque fois que je l’exécute ça check avec l'UPDATE puis ça rajoute toutes mes lignes déjà créer donc je me retrouve avec deux fois plus de lignes...

    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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    BEGIN TRANSACTION maTransaction
     
    DECLARE @errors INT --On déclare une variable qui sera destiné à accueillir nos erreurs
    SET @errors = 0
     
    BEGIN
    UPDATE	INCIDENTS
    SET		Id_entreprise=E.Id_entreprise,
    		Id_naf=C.Id_naf, 
    		Id_type=H.Id_type, 
    		Id_geographie=G.Id_geographie, 
    		Id_date=D.PK_Date, 
    		Montant=T.Montant, 
    		Date_info=T.Date_info, 
    		Date_pub=T.Date_pub, 
    		Date_maj=T.Date_maj
    FROM		INCIDENTS AS I
    INNER JOIN      TEMP AS T
    			ON Raison_Sociale = T.Raison_Sociale
    			AND Siren = T.Siren
    INNER JOIN  ENTREPRISES AS E
    			ON T.Raison_Sociale = E.Raison_Sociale
    			AND T.Siren = E.Siren
    INNER JOIN	CODE_NAF AS C
    			ON T.Naf = C.Naf
    INNER JOIN	GEOGRAPHIE AS G
    			ON T.Departement = G.Code_departement
    INNER JOIN	TYPES_INCIDENTS AS H
    			ON T.Type = H.Type
    			AND T.Type_codinf = H.Type_codinf	
    INNER JOIN  DimDate AS D
    			ON T.Date_maj = (SELECT CONVERT(date, D.PK_Date, 112))
     
    SET @errors = @errors + @@ERROR
     
    INSERT	INCIDENTS
    (
    	Id_entreprise
    	, Id_naf
    	, Id_date
    	, Id_geographie
    	, Date_info
    	, Date_maj
    	, Date_pub
    	, Montant
    	, Id_type
    )
    SELECT		E.Id_entreprise
    		, C.Id_Naf
    		, D.PK_Date
    		, G.Id_geographie
    		, T.Date_info
    		, T.Date_maj
    		, T.Date_pub
    		, T.Montant
    		, H.Id_type
     
    FROM		TEMP AS T
    INNER JOIN  ENTREPRISES AS E
    			ON T.Raison_Sociale = E.Raison_Sociale
    			AND T.Siren = E.Siren
    INNER JOIN	CODE_NAF AS C
    			ON T.Naf = C.Naf
    INNER JOIN	GEOGRAPHIE AS G
    			ON T.Departement = G.Code_departement
    INNER JOIN	TYPES_INCIDENTS AS H
    			ON T.Type = H.Type
    			AND T.Type_codinf = H.Type_codinf	
    INNER JOIN  DimDate AS D
    			ON T.Date_maj = (SELECT CONVERT(date, D.PK_Date, 112))
     
    SET @errors = @errors + @@ERROR
     
    IF @errors = 0 --Si errors est égale à 0, donc s'il n'y a eu aucune erreur
    	COMMIT TRANSACTION maTransaction -- On commit la transaction
    ELSE --S'il y a eu des erreurs
    	ROLLBACK TRANSACTION maTransaction --On annule tous les changements de cette transaction

    Merci d'avance si vous arrivez a m'aider...

  12. #12
    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
    Si j'ai une différence au niveau du champs Adresse par exemple entre deux enregistrement, ça me crée 2 entreprises avec le même Siren (damnation !)
    Il vous traiter ceux là à part, et vous n'aurez pas d'autre choix que de résoudre le conflit manuellement ... car vous seul ou vos collègues peuvent déterminer quel est le bon / le plus à jour.
    Vous pouvez les mettre dans une table à part, ou les marquer avec une colonne de type bit. Courage !

    @++

  13. #13
    Nouveau membre du Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Mars 2011
    Messages
    60
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Finance

    Informations forums :
    Inscription : Mars 2011
    Messages : 60
    Points : 29
    Points
    29
    Par défaut
    Citation Envoyé par elsuket Voir le message
    Il vous traiter ceux là à part, et vous n'aurez pas d'autre choix que de résoudre le conflit manuellement ... car vous seul ou vos collègues peuvent déterminer quel est le bon / le plus à jour.
    Vous pouvez les mettre dans une table à part, ou les marquer avec une colonne de type bit. Courage !

    @++
    Goupssss j'avais pas vu votre réponse alors que j'ai fait une modification de mon post...
    Finalement j'ai réussi en faisant un WHERE sur la Date la plus récente dans ma table TEMP...

    Et ca fonctionne plutot bien je crois

    Mon seul problème reste l'UPDATE...

  14. #14
    Candidat au Club
    Inscrit en
    Février 2011
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Février 2011
    Messages : 1
    Points : 4
    Points
    4
    Par défaut
    Je déterre le post étant donné que j'avais le même problème et que ça pourra dépanner à l'avenir.
    Même si on peut faire autrement, le MERGE est plus rapide pour traiter des mises à jour.

    Le problème vient d'ici (en rouge):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MERGE INTO ENTREPRISES E
    USING (SELECT Id_Temp, Siren, Raison_Sociale, Adresse, Ville, Cp FROM TEMP) T
        ON ( E.Siren = T.Siren AND E.Siren IS NULL) -- Condition de correspondance
    WHEN MATCHED THEN -- Si Vraie
      UPDATE SET E.Siren = T.Siren
    WHEN NOT MATCHED THEN by target-- Si faux
      INSERT (E.Siren, E.Raison_Sociale, E.Adresse, E.Ville, E.Cp) VALUES (T.Siren, T.Raison_Sociale, T.Adresse, T.Ville, T.Cp)
    La liste d'insertion de colonne utilisée dans l'instruction MERGE ne peut pas contenir d'identificateurs en plusieurs parties. Utilisez à la place des identificateurs en une partie.

    Ce qu'il appelle "identificateur en plusieurs parties" était l'ajout de l'alias dans le nom de colonne alors que l'on s'adresse forcément à la table nommée juste avant (ici c'est le "by target" en vert).
    Le "by target" n'est pas obligatoire mais ça permet de comprendre ce que l'on fait. J'imagine que par défaut il doit insérer les tuples dans la table cible...

    Au final ça marche mieux quand on l'écrit comme ça (je ne parle pas de la condition de correspondance qui n'a pas de sens):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    MERGE INTO ENTREPRISES E
    USING (SELECT Id_Temp, Siren, Raison_Sociale, Adresse, Ville, Cp FROM TEMP) T
        ON ( E.Siren = T.Siren AND E.Siren IS NULL) -- Condition de correspondance
    WHEN MATCHED THEN -- Si Vraie
      UPDATE SET E.Siren = T.Siren
    WHEN NOT MATCHED THEN by target-- Si faux
      INSERT (Siren, Raison_Sociale, Adresse, Ville, Cp) VALUES (T.Siren, T.Raison_Sociale, T.Adresse, T.Ville, T.Cp)

Discussions similaires

  1. [XL-2003] verifier si cette boucle d'enregistrement sur une feuille d'excel est bonne
    Par amine2613 dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 22/04/2009, 10h05
  2. Verifier la présence d'un service
    Par Yogy dans le forum Windows Communication Foundation
    Réponses: 1
    Dernier message: 07/05/2008, 15h23
  3. Tester la présence d'un enregistrement dans une table ?
    Par Evocatii dans le forum Requêtes
    Réponses: 5
    Dernier message: 25/02/2008, 21h02
  4. verifier la présence d'un fichier
    Par woody80 dans le forum ActionScript 1 & ActionScript 2
    Réponses: 2
    Dernier message: 17/01/2008, 14h37
  5. Test de la présence d'un enregistrement
    Par nellynew dans le forum Access
    Réponses: 1
    Dernier message: 18/05/2006, 15h03

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