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 :

Conserver l'ordre lors de l'import d'un fichier [2008R2]


Sujet :

Développement SQL Server

  1. #1
    Invité
    Invité(e)
    Par défaut Conserver l'ordre lors de l'import d'un fichier
    Hello.
    Je fais l'import de fichier Errorlog dans une table pour surveiller mes instances.
    Cependant, une fois que c'est fait, je n'ai rien qui peut me garantir que je conserve l'ordre du fichier source car pour un même datetime, je peux avoir plusieurs lignes.
    Est-ce que l'un d'entre vous aurait un moyen de conserver l'ordre de façon sûr ?
    Est-ce qu'avec mon bulk, je peux éventuellement avoir une PK incrémenté dans la table cible ?

    Ce n'est pas un problème majeur, mais ça me turlupine fortement.
    Merci d'avance pour vos idées.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    CREATE TABLE [files].[one_errorlog]( [line] [nvarchar](2000) NULL ) 
    GO
     
    truncate table files.one_errorlog
     
    BULK INSERT files.one_errorlog
    FROM 'S:\toto\ERRORLOG' 
    WITH (DATAFILETYPE = 'widechar', FIELDTERMINATOR = '\t', ROWTERMINATOR = '\n')
     
    select line from files.one_errorlog

  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
    En utilisant ROW_NUMBER avec un simple ORDER BY (SELECT 0)) tu ne devrais pas affecter l'ordre des lignes de la table juste après avoir insérer tes données :

    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
    CREATE TABLE #ErrLog
    (
     LogCol NVARCHAR(max) NULL
    )
     
    BULK INSERT #ErrLog 
    FROM 'C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQLSERVER\MSSQL\Log\ERRORLOG.1' 
    WITH 
    (
     FIRSTROW = 6, 
     DATAFILETYPE = 'widechar'
    )
     
    SELECT 
    	ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS numline,
    	LogCol
    from #ErrLog
    ++

  3. #3
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    J'avais lu dans un bouquin préparant à une certification SQL Server (mais dont je ne me souvient plus le nom) qu'il ne fallait surtout pas faire d'hypothèse sur l'ordre des enregistrements retourné par un SELECT sans ORDER BY. Si l'ordre à de l'importance, il faut spécifier un ORDER BY (et ne pas se dire un truc du genre "c'est le même ordre que mon clustered index", car ce n'est pas forcément vrai).

    Donc pour garantir l'ordre, dans la table de destination il faut une colonne sur laquelle on puisse faire un ORDER BY.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  4. #4
    Invité
    Invité(e)
    Par défaut
    Je suis bien d'accord mais tu proposes de faire quoi alors parce que mon fichier errorlog n'a pas de colonne où je puisse faire un order by sûr.
    Dernière modification par al1_24 ; 04/03/2015 à 16h05. Motif: Citation inutile

  5. #5
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par 7gyY9w1ZY6ySRgPeaefZ Voir le message
    Je suis bien d'accord mais tu proposes de faire quoi alors parce que mon fichier errorlog n'a pas de colonne où je puisse faire un order by sûr.
    Il te faut une colonne avec la propriété IDENTITY pour pouvoir différencier les enregistrements. Oui mais voilà : comment faire le BULK INSERT alors ?
    Plusieurs personnes conseillent la même chose :
    - créer une vue sur la table destination (avec les mêmes colonnes que dans ton fichier, donc sans la colonne IDENTITY)
    - faire le BULK INSERT sur cette vue

    Exemples :
    http://noelmckinney.com/2010/08/bulk-insert-into-view/
    http://www.bidn.com/blogs/marcoadf/b...dentity-column

    Sinon, il y a toujours SSIS, ou d'autres outils ETL...
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  6. #6
    Invité
    Invité(e)
    Par défaut
    Citation Envoyé par pcaboche Voir le message
    Plusieurs personnes conseillent la même chose :
    - créer une vue sur la table destination (avec les mêmes colonnes que dans ton fichier, donc sans la colonne IDENTITY)
    - faire le BULK INSERT sur cette vue
    Ok merci!
    Je me doutais bien que ce problème avait fait cogiter du monde avant moi et qu'il y avait une solution (un peu) tordue pour y remédier.
    Merci bien !

  7. #7
    Invité
    Invité(e)
    Par défaut
    Testé, validé, vendu !
    Gros merci.

  8. #8
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Mais de rien !
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  9. #9
    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

    Pour information, êtes-vous certains que cette "technique" fonctionne en toutes circonstances ?

    Je pense notamment au cas où la parallélisation viendrait s'en mêler au moment du bulk insert. Il me semble en effet qu'il n'y a pas de moyen de garantir l'ordre d’insertion avec un BULK...

  10. #10
    Rédacteur
    Avatar de pcaboche
    Homme Profil pro
    Inscrit en
    Octobre 2005
    Messages
    2 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : Singapour

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 785
    Points : 9 716
    Points
    9 716
    Par défaut
    Citation Envoyé par aieeeuuuuu Voir le message
    Il me semble en effet qu'il n'y a pas de moyen de garantir l'ordre d’insertion avec un BULK...
    Pas tout à fait.

    En fait, tu peux préciser comment le fichier est ordonné avec la clause ORDER. Si cet ordre correspond à l'index clustered de la table, alors le BULK "optimise" l'insertion (en gros, il insère dans l'ordre du fichier). Mais si on ne précise rien :
    By default, the bulk insert operation assumes the data file is unordered.


    Bref, pour être vraiment sûr, il faudrait écrire un programme pour numéroter les lignes du fichier, avant de faire un BULK INSERT ... ORDER.
    "On en a vu poser les armes avant de se tirer une balle dans le pied..."
    -- pydévelop

    Derniers articles:

    (SQL Server) Introduction à la gestion des droits
    (UML) Souplesse et modularité grâce aux Design Patterns
    (UML) Le Pattern Etat
    Autres articles...

  11. #11
    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
    Citation Envoyé par pcaboche Voir le message
    J'avais lu dans un bouquin préparant à une certification SQL Server (mais dont je ne me souvient plus le nom) qu'il ne fallait surtout pas faire d'hypothèse sur l'ordre des enregistrements retourné par un SELECT sans ORDER BY. Si l'ordre à de l'importance, il faut spécifier un ORDER BY (et ne pas se dire un truc du genre "c'est le même ordre que mon clustered index", car ce n'est pas forcément vrai).

    Donc pour garantir l'ordre, dans la table de destination il faut une colonne sur laquelle on puisse faire un ORDER BY.
    Très juste et il faut toujours garder cela à l'esprit. Dans ce cas particulier il n'y aurait pas de souci en admettant que le bulk insert se fasse de manière non parallèle (possible de le forcer en effet au prix d'une certaine performance mais pour un fichier de log SQL Server je pense qu'il n'y aurait pas eu de problème). Le SELECT sans ORDER BY retrouverait bien nos données dans l'ordre désiré en forçant un "allocation order scan" en utilisation le hint TABLOCK par exemple. Dans ce contexte on crée une table heap et les pages sont allouées en suivant l'ordre d'insertion des lignes de bulk insert. Ensuite il suffit de lire ces mêmes données dans l'ordre d'allocation des pages via la page IAM. On peut le vérifier en récupérant la stack lors de l'exécution de la requête avec le hint (tablock) :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    SELECT 
    	ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS numline,
    	LogCol
    from #ErrLog (TABLOCK)
    Nom : developpez_allocation_order_scan.jpg
Affichages : 613
Taille : 139,6 Ko

    Mais ceci est valable uniquement que dans certains cas particuliers et j'aurais tendance à dire qu'il vaut mieux privilégier une méthode où l'on contrôle ce que l'on fait via des commandes bien connus.
    Si on veut numéroter à la source on peut potentiellement utiliser la procédure stockée sp_readerrorlog de la manière suivante. Ensuite il suffit d'exploiter le contenu de la table pour le besoin voulu.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    create table #sqllog
    (
    	id int identity(1,1),
    	LogDate datetime2,
    	ProcessInfo varchar(100),
    	[Text] varchar(max)
    )
     
    insert #sqllog (LogDate, ProcessInfo, [Text])
    exec sp_readerrorlog
    ++

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

Discussions similaires

  1. pb lors de l'importation multiple de fichiers txt
    Par mouche dans le forum VBA Access
    Réponses: 4
    Dernier message: 18/12/2007, 11h15
  2. Problème lors de l'import d'un fichier excel
    Par mattyeux dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 20/11/2007, 14h26
  3. Réponses: 7
    Dernier message: 29/06/2007, 15h56
  4. Réponses: 4
    Dernier message: 04/04/2007, 07h46
  5. Réponses: 6
    Dernier message: 20/12/2006, 13h21

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