Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 14/02/2011, 11h35   #1
Expert Confirmé
 
Avatar de Marco46
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 457
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Lot (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2005
Messages : 1 457
Points : 2 796
Points : 2 796
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 :
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 :
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 :
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 :
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 ?
__________________
"Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
Kenneth E. Boulding

"/home/earth is 102% full ... please delete anyone you can."
Inconnu
Marco46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 11h47   #2
Expert Confirmé
 
Avatar de Marco46
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 457
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Lot (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2005
Messages : 1 457
Points : 2 796
Points : 2 796
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.
__________________
"Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
Kenneth E. Boulding

"/home/earth is 102% full ... please delete anyone you can."
Inconnu
Marco46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 12h35   #3
Membre Expert
 
Homme Etienne ZINZINDOHOUE
Ingénieur développement
Inscription : mars 2010
Messages : 1 138
Détails du profil
Informations personnelles :
Nom : Homme Etienne ZINZINDOHOUE
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Ingénieur développement
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2010
Messages : 1 138
Points : 2 466
Points : 2 466
Envoyer un message via Yahoo à zinzineti
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 :
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
__________________
Etienne ZINZINDOHOUE
Billets-Articles
zinzineti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 14/02/2011, 14h04   #4
Expert Confirmé
 
Avatar de Marco46
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 457
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Lot (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2005
Messages : 1 457
Points : 2 796
Points : 2 796
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
__________________
"Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
Kenneth E. Boulding

"/home/earth is 102% full ... please delete anyone you can."
Inconnu
Marco46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 00h13   #5
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 950
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 950
Points : 17 769
Points : 17 769
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 +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 10h28   #6
Expert Confirmé
 
Avatar de Marco46
 
Homme
Développeur informatique
Inscription : août 2005
Messages : 1 457
Détails du profil
Informations personnelles :
Sexe : Homme
Âge : 30
Localisation : France, Lot (Midi Pyrénées)

Informations professionnelles :
Activité : Développeur informatique

Informations forums :
Inscription : août 2005
Messages : 1 457
Points : 2 796
Points : 2 796
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.
__________________
"Toute personne croyant qu'une croissance exponentielle peut durer indéfiniment dans un monde fini est soit un fou, soit un économiste."
Kenneth E. Boulding

"/home/earth is 102% full ... please delete anyone you can."
Inconnu
Marco46 est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 15/02/2011, 10h53   #7
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
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...
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 10h29.


 
 
 
 
Partenaires

Hébergement Web