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 :

Récupération de données


Sujet :

Développement SQL Server

  1. #1
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut Récupération de données
    Bonjour,

    voici ma problématique :

    Je participe au développement d'une application pour une entreprise que nous appellerons N pour le compte d'un éditeur de logiciel que nous appellerons L.

    L a jadis fournit un logiciel de gestion à N que nous nommerons O.
    Aujourd'hui N a demandé à L de lui refondre son SI en fusionnant tous les petits softs gravitant autour de O dans O qui devient alors T.

    Mon chef de projet m'a demandé de travailler sur l'import des données de O vers T.
    O est donc une gestion commerciale standard spécialisée dans le domaine de N.
    T est donc cette gestion commerciale + tous les ajouts réalisés à la demande de N.

    Je dois donc fusionner les données de O et des softs autour dans T. La description de l'analyse correspond dans les grandes lignes.

    La procédure mise au point avec le client est la suivante :
    Pour chaque fichier de la BDD (de O), nous leur fournissons un export CSV + la description du fichier de destination (BDD de T). Ils font les conversions à la main eux-même puis on intègre.

    Pour l'intégration des données, nous comptions utiliser les requêtes de type BULK INSERT.

    J'en arrive enfin à la problématique principale, à savoir l'intégration dans la nouvelle analyse des clefs autoincrement. La plupart des fichiers ayant un identifiant automatique, et cet identifiant étant utilisé en clef étrangère, il nous faut récupérer dans la BDD de T les PK ID autoincrement avec les bonnes valeurs.

    Seulement pas moyen d'y arriver.

    Voici comment je procède. Pour tester vous pouvez vous créer une BDD de test.

    La création de la table de test se fait comme ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    CREATE TABLE [dbo].[TEST_BULK] (
      [TB_PK_ID] bigint IDENTITY(1, 1) NOT NULL,
      [TB_DATA_1] varchar(10) COLLATE French_CI_AS NULL,
      PRIMARY KEY CLUSTERED ([TB_PK_ID])
    )
    ON [PRIMARY]
    GO
    La table de test est donc constituée de 2 colonnes, une ID auto et une varchar(10).

    Maintenant nous allons nous occuper de l'import via BULK INSERT.

    Pour se faire, il nous faut d'abord un fichier de format de la table TEST_BULK.
    Ouvrez une console DOS et exécutez la ligne de commande suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    bcp test.dbo.TEST_BULK format nul -f test_bulk.fmt -S 127.0.0.1\EXPRESS2008R2 -U vd -P vd
    J'ai donc la BDD sur mon poste local, l'instance s'appelle EXPRESS2008R2, user vd, mdp vd et j'obtiens en sortie un fichier de format test_bulk.fmt (généralement il sort dans MesDocuments).

    Préparez ensuite un CSV à importer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    6;TOTO
    7;TATA
    8;TITI
    9;TUTU
    10;TETE
    La première colonne est l'identifiant automatique. La table dans la BDD venant d'être créée l'id auto sera à 1 pour le premier enregistrement inséré et nous on veut y mettre 6.

    La requête BULK INSERT à exécuter est la suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
     
    USE [test]
    GO
     
    BULK INSERT [dbo].TEST_BULK FROM 'D:\scripts.sql\export.TEST_BULK.csv' 
    	WITH (	FIRSTROW = 1, 
        		MAXERRORS = 0,
        		DATAFILETYPE = 'char', 
                FIELDTERMINATOR = ';', 
                FORMATFILE = 'D:\scripts.sql\TEST_BULK.fmt', 
                ROWTERMINATOR = '\r\n', 
                KEEPIDENTITY, 
                KEEPNULLS)
    GO
    Attention aux chemins d'accès aux fichiers .csv et .fmt.

    La requête s'exécute sans problème, les données sont importées, sauf que mon problème c'est que pour les id auto ça coince.

    J'obtiens les valeurs suivantes : 55, 56, 57, 12337 et 918535151 alors que je devrais avoir 6, 7, 8, 9, et 10 pour la colonne TB_PK_ID.

    Quelqu'un aurait-il une idée sur le pourquoi du comment ?

  2. #2
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    Autre chose que j'ai oublié, après la génération du fichier de format, je me vois dans l'obligation de le modifier à la main pour qu'il soit fonctionnel.

    La colonne 1 est marquée SQLBIT de longueur 1 alors qu'elle devrait être marquée en SQLBIGINT de longueur 8.

    J'ai trouvé bizarre l'utilisation de bcp pour la génération du fichier de format, il pose des questions dont les réponses sont dans la description des fichiers. Bref, j'ai peut être une utilisation de bcp qui est mauvaise.

  3. #3
    Membre émérite

    Homme Profil pro
    Chargé de Développement et d'Analyse de données
    Inscrit en
    Mars 2010
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé de Développement et d'Analyse de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 278
    Points : 2 856
    Points
    2 856
    Par défaut
    2 possibilités :

    1.) soit tu ne poses pas d'auto-incrément sur la colonne TB_PK_ID

    2.) soit tu réinitialises à chaque fois la valeur de la colonne auto-incrément.
    /!\ Attention à la primary key => unique => pas de doublon ! (pour avoir des doublons tu seras obligé de faire sauter la clé primaire qui est posée sur la colonne TB_PK_ID !

    Comment faire dans le cas 2.) ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    --Connaitre la valeur du dernier incrément 
    SELECT IDENT_CURRENT('TEST_BULK')
     
    --Réinitialiser la colonne auto-incrément 
    DBCC CHECKIDENT('TEST_BULK', RESEED, 5 );
    Réinitiaiser TEST_BULK à 5 signifie que l'insertion suivante va prendre la valeur 6

  4. #4
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    Pour les clefs autoincrement en PK et FK j'ai pas le choix c'est la structure de la BDD qui est comme ça et c'est très bien.

    Simplement il faut conserver les valeurs pour les FK.

    Concernant la fonction CHECKIDENT, j'ai pris comme exemple un démarrage à 5 pour la PK mais c'est pas nécessairement le cas. Il s'agit de fichiers utilisés depuis plusieurs années, il y a donc des trous un peu partout. C'était juste à des fins de test. Il n'est donc pas possible d'utiliser cette fonction dans mon contexte puisque la requête BULK INSERT insère en bloc tout un fichier CSV.

    Mais merci pour l'aide

  5. #5
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 899
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Expert bases de données / SQL / MS SQL Server / Postgresql
    Secteur : Conseil

    Informations forums :
    Inscription : Mai 2002
    Messages : 21 899
    Points : 53 140
    Points
    53 140
    Billets dans le blog
    6
    Par défaut
    Pour ma part, dans un tel cas de figure je rajoute à toutes les tables une colonne intitulée _OLD_KEY et dont la valeur est la clef externe de l'ancienne base.
    Puis je fait des requêtes d'update pour matcher les anciennes références avec les nouvelles clefs auto incrémentée.
    Enfin je remet en place l'IRD
    puis, au bout d'un an, je supprime ces anciennes clef...

    A +

  6. #6
    Expert éminent sénior
    Avatar de Marco46
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2005
    Messages
    4 413
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Août 2005
    Messages : 4 413
    Points : 19 609
    Points
    19 609
    Par défaut
    C'est une solution que l'on avait évoqué avec le chef de projet mais on a 150 tables dans la BDD.

    Ça en fait des scripts UPDATE à écrire ...

    Donc au niveau des outils employés (bcp, BULK INSERT, ...) il se passe quoi d'après vous ? C'est un bug de SQLServer ? Une mauvaise utilisation de ma part ? Un problème de config quelconque ?

    Merci.

  7. #7
    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
    Citation Envoyé par SQLpro Voir le message
    Pour ma part, dans un tel cas de figure je rajoute à toutes les tables une colonne intitulée _OLD_KEY et dont la valeur est la clef externe de l'ancienne base.
    Puis je fait des requêtes d'update pour matcher les anciennes références avec les nouvelles clefs auto incrémentée.
    Enfin je remet en place l'IRD
    puis, au bout d'un an, je supprime ces anciennes clef...

    A +
    Pareil...

Discussions similaires

  1. Réponses: 4
    Dernier message: 05/04/2004, 10h09
  2. Réponses: 2
    Dernier message: 20/02/2004, 08h47
  3. [ DB2] => [ORACLE] Récupération de données
    Par LeDid dans le forum DB2
    Réponses: 3
    Dernier message: 25/06/2003, 17h10
  4. Réponses: 13
    Dernier message: 20/03/2003, 08h11
  5. [XMLRAD] récupération de donnée
    Par Mitch79 dans le forum XMLRAD
    Réponses: 7
    Dernier message: 30/01/2003, 15h36

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