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 :

SPlit sur traitement de Batch


Sujet :

Développement SQL Server

  1. #1
    Futur Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 12
    Points : 6
    Points
    6
    Par défaut SPlit sur traitement de Batch
    Bonjour,
    j'aimerais savoir s'il existe une méthode simple et rapide ( dans l'idéale)
    pour spliter un champ en plusieurs lors d'un traitement d'insertion en masse
    le Hic c'est que les sous ensemble n'ont ni la meme longueur ni le meme nombre.

    ex : champ mnemo = 'W.C211.SVID'
    a répartir en GROUPE = W , TRONCON = C211 et DEFAUT = SVID
    ou encore mnemo = 'C.J90.CV2.CAM1.CDEA'
    a répartir en GROUPE = C , TRONCON = J90 EQUIPEMENT CV2, ORGANE CAM1 et DEFAUT = CDEA

    voyez vous une solution ensembliste ? pourt ma part j'ai du mal ...
    merci d'avance
    dunkansk8,
    vous salut bien
    www.dunkansk8.org

  2. #2
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 768
    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 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    Si la structure de votre champ mémo était la même ce serait facile.
    Par exemple si votre structure est toujours :
    X.Y[Y][Y].Z[Z][Z].T[T][T].U[U][U]

    alors il vous suffit de faire une projection pour découpage de la chaîne de caractères sur une table de nombre et de proposer de parser à chaque rencontre du caractère '.'.

    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
     
    CREATE TABLE T (MEMO VARCHAR(32))
     
    INSERT INTO T VALUES ('C.J90.CV2.CAM1.CDEA')
    INSERT INTO T VALUES ('D.JF36.CB142.SDF.ZE')
     
    CREATE TABLE N (I INT NOT NULL PRIMARY KEY)
    INSERT INTO N VALUES (1)
    INSERT INTO N VALUES (2)
    INSERT INTO N VALUES (3)
    INSERT INTO N VALUES (4)
    INSERT INTO N VALUES (5)
    INSERT INTO N VALUES (6)
    INSERT INTO N VALUES (7)
    INSERT INTO N VALUES (8)
    INSERT INTO N VALUES (9)
    INSERT INTO N VALUES (0)
     
    INSERT INTO N
    SELECT T1.I + 10*T2.I
    FROM   N AS T1
           CROSS JOIN N AS T2
    WHERE  T1.I + 10*T2.I > 9

    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
    -- requête de parsing :
    WITH
    TA AS
    (
    SELECT *
    FROM   T
           INNER JOIN N
                 ON SUBSTRING(MEMO, I, 1) = '.'
    ),
    TB AS
    (
    SELECT *, COALESCE((SELECT MAX(I) 
                       FROM   TA AS T2
                       WHERE  T2.MEMO = T1.MEMO
                       AND    T2.I < T1.I), 0) + 1 AS DEBUT
    FROM   TA AS T1
    )
    SELECT MEMO, SUBSTRING(MEMO, DEBUT, I-DEBUT) AS PARSE,
           ROW_NUMBER() OVER(PARTITION BY MEMO ORDER BY I) AS ORDRE
    FROM   TB
    résultat :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    MEMO                             PARSE                            ORDRE
    -------------------------------- -------------------------------- --------------------
    C.J90.CV2.CAM1.CDEA              C                                1
    C.J90.CV2.CAM1.CDEA              J90                              2
    C.J90.CV2.CAM1.CDEA              CV2                              3
    C.J90.CV2.CAM1.CDEA              CAM1                             4
    D.JF36.CB142.SDF.ZE              D                                1
    D.JF36.CB142.SDF.ZE              JF36                             2
    D.JF36.CB142.SDF.ZE              CB142                            3
    D.JF36.CB142.SDF.ZE              SDF                              4

    A vous de jouer après !

    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

  3. #3
    Futur Membre du Club
    Inscrit en
    Janvier 2004
    Messages
    12
    Détails du profil
    Informations forums :
    Inscription : Janvier 2004
    Messages : 12
    Points : 6
    Points
    6
    Par défaut
    Merci pour cette réponse fort intéressante, j'avais juste oublié un détail, mes serveurs sont sous 2000 et je ne peux gerer cette synthaxe.
    Une migration n'etant pas encore d'actualité. j'ai envisagé une solution par Curseur ... Ho le vilain je sais ...
    je split donc mes données via un curseur en capitalisant cette opération par le stockage dans une table intermediaire contenant le MNEMO et ses resultantes. Ce traitement est lent lors de la première execution.
    Mais comme ce qui est fait n'est plus a faire,les fois suivantes ,je ne split que les données que je n'aurais pas déja splité.

    voici le code
    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
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
     
    IF OBJECTPROPERTY( OBJECT_ID('P_A_ImportPcVue'), 'IsProcedure') = 1
    BEGIN
        DROP PROCEDURE dbo.P_A_ImportPcVue
        DELETE FROM dbo.T_PROCEDURE_PRC WHERE PRC_NAME = 'P_A_ImportPcVue'
    END   
    GO
     
    CREATE PROCEDURE dbo.P_A_ImportPcVue 
    	@LaDate DATETIME
    AS
     
    SET NOCOUNT ON
     
    DECLARE @FileExist INT,
    	@Fichier Varchar(128),
    	@Chemin Varchar(255),
     
    	@Mnemo Varchar(128),
            @GROUPE CHAR(1),
    	@TRONCON VARCHAR(6),
    	@EQUIPEMENT VARCHAR(30),
    	@ORGANE VARCHAR(10),
    	@DEFAUT VARCHAR(50),
    	@MAX INT,
    	@SQLSTRING VARCHAR(255)
     
    IF EXISTS (SELECT name FROM tempdb.dbo.sysobjects WHERE name = 'tmppcvue' AND type = 'U')
       DROP Table tempdb.dbo.tmppcvue
     
    Create Table tempdb.dbo.tmppcvue (	
    	Ladate VARCHAR (14) NOT NULL ,
    	Heure VARCHAR (8) NOT NULL ,
    	Mnemo VARCHAR (128) NOT NULL ,
    	Detail VARCHAR (128) NOT NULL ,
    	Etat VARCHAR (128) NOT NULL
    ) 
     
    --EXEC master.dbo.xp_cmdshell 'NET USE "\\172.28.21.1\e$" /USER:user mdp, NO_OUTPUT
    --EXEC master.dbo.xp_cmdshell 'NET USE "\\172.28.21.4\e$" /USER:user mdp, NO_OUTPUT
     
     
    SET @Fichier = CONVERT(VARCHAR(8),@LaDate,112) + ' Journal PcVue.txt'
    SET @Chemin = '\\172.28.21.1\e$\' + RTRIM(@Fichier)
     
    EXEC master.dbo.xp_fileexist @Chemin , @FileExist OUTPUT
    if (@FileExist = 1)
    BEGIN
    	SET @SQLSTRING = 'BULK INSERT tempdb.dbo.tmpPcvue'+
    			 ' FROM ''' +  RTRIM(@Chemin) + ''''+
    	                 ' WITH (FIELDTERMINATOR = '';'',ROWTERMINATOR = ''\n'',CODEPAGE = ''ACP'' )'
     
    	EXEC master.dbo.sp_sqlexec @SQLSTRING
    END
    ELSE
    BEGIN
    	SET @Chemin = '\\172.28.21.4\e$\' + RTRIM(@Fichier)
    	EXEC master.dbo.xp_fileexist @Chemin , @FileExist OUTPUT
     
    	if (@FileExist = 1)
    	BEGIN
    		SET @SQLSTRING = 'BULK INSERT tempdb.dbo.tmpPcvue'+
    				 ' FROM ''' +  RTRIM(@Chemin) + ''''+
    		                 ' WITH (FIELDTERMINATOR = '';'',ROWTERMINATOR = ''\n'',CODEPAGE = ''ACP'' )'
     
    		EXEC master.dbo.sp_sqlexec @SQLSTRING
    END
    	ELSE
    		Print RTRIM(@Fichier) + ' n''est pas présent sur les serveurs.'
    END
     
    IF @@Error <> 0
    	GOTO Gestion_Erreur
     
    DECLARE CursField CURSOR 
    FOR 
    SELECT MNEMO
    FROM tempdb.dbo.tmppcvue
    WHERE MNEMO not in (SELECT MNEMO FROM dbo.T_IMPORTMNEMO_IMN)
    GROUP BY Mnemo 
     
     
    OPEN CursField
    FETCH CursField INTO @Mnemo
    WHILE @@FETCH_STATUS = 0
    BEGIN
     
    SET @GROUPE = ''
    SET @TRONCON = ''
    SET @EQUIPEMENT = ''
    SET @ORGANE = ''
    SET @DEFAUT = ''
     
      SELECT @MAX = MAX(position)
        FROM dbo.fn_SplitShort(@Mnemo,'.')
     
      SELECT @DEFAUT = value 
        FROM dbo.fn_SplitShort(@Mnemo,'.')
        WHERE position = @MAX
     
      SELECT @GROUPE = value 
        FROM dbo.fn_SplitShort(@Mnemo,'.')
        WHERE position <> @MAX AND position = 1
     
      SELECT @TRONCON = value 
        FROM dbo.fn_SplitShort(@Mnemo,'.')
        WHERE position <> @MAX AND position = 2
     
      SELECT @EQUIPEMENT = value 
        FROM dbo.fn_SplitShort(@Mnemo,'.')
        WHERE position <> @MAX AND position = 3
     
      SELECT @ORGANE = value 
        FROM dbo.fn_SplitShort(@Mnemo,'.')
        WHERE position <> @MAX AND position = 4
     
      INSERT INTO dbo.T_IMPORTMNEMO_IMN (GROUPE,TRONCON,EQUIPEMENT,ORGANE,DEFAUT,MNEMO) 
    	VALUES (@GROUPE,@TRONCON,@EQUIPEMENT,@ORGANE,@DEFAUT,@MNEMO)
     
    FETCH CursField INTO @Mnemo
    END
    CLOSE CursField
    DEALLOCATE CursField
     
    IF @@Error <> 0
    	GOTO Gestion_Erreur
     
    INSERT INTO dbo.T_EVENEMENT_EVT 
      SELECT e.EQP_ID,CONVERT(datetime, ladate + ' ' + Heure ),l.LEV_ID 
        FROM tempdb.dbo.tmppcvue t
          LEFT OUTER JOIN dbo.T_IMPORTMNEMO_IMN i ON t.MNEMO = i.MNEMO
          LEFT OUTER JOIN dbo.T_LIBELLEEVENT_LEV l ON t.ETAT = l.LEV_LIBELLE
          LEFT OUTER JOIN dbo.T_EQUIPEMENT_EQP e ON e.GROUPE = i.GROUPE AND e.TRONCON = i.TRONCON AND e.DEFAUT = i.DEFAUT
    						 	AND e.EQUIPEMENT = i.EQUIPEMENT AND e.ORGANE = i.ORGANE						 	
     
    IF @@Error <> 0
    	GOTO Gestion_Erreur
     
    IF EXISTS (SELECT name FROM tempdb.dbo.sysobjects WHERE name = 'tmppcvue' AND type = 'U')
       DROP Table tempdb.dbo.tmppcvue
     
    RETURN
     
    Gestion_Erreur:
    	Declare @LibErreur as Varchar(255)
    	Select @LibErreur = description from master.dbo.sysmessages where error = @@Error
    	Print 'Erreur dans P_A_ImportPcVue : N° '+LTRIM(STR(@@Error)) + ' ' + @LibErreur
     
    GO
     
    INSERT INTO dbo.T_PROCEDURE_PRC(PRC_NAME, PRC_COMMENT)
    VALUES('P_A_ImportPcVue', 'Importation des Journaux PCVUE')
     
    GO
    si toute fois vous connaissez une solution meilleur je suis preneur
    dunkansk8,
    vous salut bien
    www.dunkansk8.org

  4. #4
    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,

    Vous pouvez peut-être vous servir de la fonction dbo.F_INITCAP proposée par SQLPro ici...

    @++

  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 768
    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 768
    Points : 52 719
    Points
    52 719
    Billets dans le blog
    5
    Par défaut
    La même chose sans CTE à l'aide de vues :

    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
    CREATE TABLE T (MEMO VARCHAR(32))
    GO
     
    INSERT INTO T VALUES ('C.J90.CV2.CAM1.CDEA')
    INSERT INTO T VALUES ('D.JF36.CB142.SDF.ZE')
     
    CREATE TABLE N (I INT NOT NULL PRIMARY KEY)
    GO
     
    INSERT INTO N VALUES (1)
    INSERT INTO N VALUES (2)
    INSERT INTO N VALUES (3)
    INSERT INTO N VALUES (4)
    INSERT INTO N VALUES (5)
    INSERT INTO N VALUES (6)
    INSERT INTO N VALUES (7)
    INSERT INTO N VALUES (8)
    INSERT INTO N VALUES (9)
    INSERT INTO N VALUES (0)
     
    INSERT INTO N
    SELECT T1.I + 10*T2.I
    FROM   N AS T1
           CROSS JOIN N AS T2
    WHERE  T1.I + 10*T2.I > 9
    GO
     
    -- requête de parsing :
    CREATE VIEW TA AS
    (
    SELECT *
    FROM   T
           INNER JOIN N
                 ON SUBSTRING(MEMO, I, 1) = '.'
    )
    GO
     
    CREATE VIEW TB AS
    (
    SELECT *, COALESCE((SELECT MAX(I) 
                       FROM   TA AS T2
                       WHERE  T2.MEMO = T1.MEMO
                       AND    T2.I < T1.I), 0) + 1 AS DEBUT
    FROM   TA AS T1
    )
    GO
     
     
    SELECT MEMO, SUBSTRING(MEMO, DEBUT, I-DEBUT) AS PARSE, I AS ORDRE
    FROM   TB
    ORDER  BY MEMO, DEBUT
    A +
    Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
    Le site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
    Blog SQL, SQL Server, SGBDR : http://blog.developpez.com/sqlpro
    Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
    Entreprise SQL SPOT : modélisation, conseils, audit, optimisation, formation...
    * * * * * Expertise SQL Server : http://mssqlserver.fr/ * * * * *

Discussions similaires

  1. [X3 V5] Nouveau traitement sur le serveur Batch
    Par guywil dans le forum SAGE
    Réponses: 1
    Dernier message: 13/07/2011, 11h19
  2. Réponses: 3
    Dernier message: 20/04/2007, 12h19
  3. Option Annuler sur traitement image
    Par richard_sraing dans le forum C#
    Réponses: 4
    Dernier message: 29/01/2007, 09h38
  4. split sur plusieurs caractères ?
    Par SpaceFrog dans le forum Général JavaScript
    Réponses: 28
    Dernier message: 08/02/2005, 21h44
  5. [String] split sur la sequence ">$<"
    Par okoax dans le forum Collection et Stream
    Réponses: 4
    Dernier message: 09/09/2004, 14h54

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