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 :

Découper une chaine en sous chaine


Sujet :

Développement SQL Server

  1. #1
    Membre du Club
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Janvier 2003
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Janvier 2003
    Messages : 85
    Points : 51
    Points
    51
    Par défaut Découper une chaine en sous chaine
    Bonjour,
    j'aimerais découpé une chaine en sous chaine. Le séparateur est le ~.
    Monchamp s'appelle GQD_REFAFFECTATION dans une table. Les sous-chaine n'ont pas une longueur fixe. et j'ai essayé avec des les fonctions charindex et substring. mais je m'arrache un peu les cheveux.


    GQD_REFAFFECTATION
    GL~CC~GCC~1075~0~1
    GL~CC~GCC~161~0~1
    GL~CC~GCC~161~0~2
    GL~CC~GCC~61~0~1
    GL~CC~GCC~61~0~111
    WOB~FAB~1360~110~18000
    WOB~FAB~1410~110~178000
    WOB~FAB~782~110~32000
    WOB~FAB~836~110~2000
    WOB~FAB~88~110~24000
    WOB~FAB~1847~110~102000
    WOB~FAB~849~1100~124000
    WOB~FAB~849~110~124000
    [/QUOTE]

    Et voici ce que je souhaite
    Col1 | Col2 | Col3 | Col4 | Col5 | Col6
    GL | CC | GCC | 1075 | 0 | 1
    GL | CC | GCC | 161 | 0 | 1
    GL | CC | GCC | 161 | 0 | 2
    GL | CC | GCC | 61 | 0 | 1
    GL | CC | GCC | 61 | 0 | 111
    WOB | FAB | 1360 | 110 | 18000 |
    WOB | FAB | 1410 | 110 | 178000 |
    WOB | FAB | 782 | 110 | 32000 |
    WOB | FAB | 836 | 110 | 2000 |
    WOB | FAB | 88 | 110 | 24000 |
    WOB | FAB | 1847 | 110 | 102000 |
    WOB | FAB | 849 | 1100 | 124000 |
    WOB | FAB | 849 | 110 | 124000 |


    merci beaucoup pour vos réponses.

    Ciao Domtel.

  2. #2
    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 : 43
    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,

    Tout dépend de ce que vous voulez faire.
    Vous pouvez créer une fonction table qui vous retourne les valeurs entre les tildes, comme suit :

    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
    CREATE FUNCTION Fn_ParseTilde (@_string varchar(max))
    	RETURNS @return TABLE
    	(
    		sub_string_1 varchar(16)
    		, sub_string_2 varchar(16)
    		, sub_string_3 varchar(16)
    		, sub_string_4 varchar(16)
    		, sub_string_5 varchar(16)
    		, sub_string_6 varchar(16)
    	)
    	WITH SCHEMABINDING
    AS
    BEGIN
    	DECLARE @pos1 tinyint
    		, @pos2 tinyint
    		, @pos3 tinyint
    		, @pos4 tinyint
    		, @pos5 tinyint
    		, @pos6 tinyint
     
    	SELECT @pos1 = CHARINDEX('~', @_string)
    		, @pos2 = CASE @pos1 WHEN 0 THEN NULL ELSE CHARINDEX('~', @_string, @pos1 + 1) END
    		, @pos3 = CASE @pos2 WHEN 0 THEN NULL ELSE CHARINDEX('~', @_string, @pos2 + 1) END
    		, @pos4 = CASE @pos3 WHEN 0 THEN NULL ELSE CHARINDEX('~', @_string, @pos3 + 1) END
    		, @pos5 = CASE @pos4 WHEN 0 THEN NULL ELSE CHARINDEX('~', @_string, @pos4 + 1) END
    		, @pos6 = CASE @pos5 WHEN 0 THEN NULL ELSE CHARINDEX('~', @_string, @pos5 + 1) END
     
    	INSERT	@return
    	SELECT	SUBSTRING(@_string, 1, CASE WHEN @pos1 = 0 THEN LEN(@_string)ELSE @pos1 - 1 END) 
    		, SUBSTRING(@_string, @pos1 + 1, CASE WHEN @pos2 = 0 THEN LEN(@_string) ELSE @pos2 - @pos1 - 1 END)
    		, SUBSTRING(@_string, @pos2 + 1, CASE WHEN @pos3 = 0 THEN LEN(@_string) ELSE @pos3 - @pos2 - 1 END)
    		, SUBSTRING(@_string, @pos3 + 1, CASE WHEN @pos4 = 0 THEN LEN(@_string) ELSE @pos4 - @pos3 - 1 END)
    		, SUBSTRING(@_string, @pos4 + 1, CASE WHEN @pos5 = 0 THEN LEN(@_string) ELSE @pos5 - @pos4 - 1 END)
    		, SUBSTRING(@_string, @pos5 + 1, CASE WHEN @pos6 = 0 THEN LEN(@_string) ELSE @pos6 - @pos5 - 1 END)
     
    	RETURN
    END
    Et :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT		I.string
    		, F.sub_string_1
    		, F.sub_string_2
    		, F.sub_string_3
    		, F.sub_string_4
    		, F.sub_string_5
    		, F.sub_string_6
    FROM		dbo.import AS I
    CROSS APPLY	dbo.Fn_ParseTilde(I.string) AS F
    Vous permet d'afficher les valeurs.

    Vous pouvez aussi créer une vue :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    CREATE VIEW v_TEST
    	WITH SCHEMABINDING
    AS
    	SELECT		I.string
    			, F.sub_string_1
    			, F.sub_string_2
    			, F.sub_string_3
    			, F.sub_string_4
    			, F.sub_string_5
    			, F.sub_string_6
    	FROM		dbo.import AS I
    	CROSS APPLY	dbo.Fn_ParseTilde(I.string) AS F
    Vous pouvez enfin réaliser un INSERT dans une autre table :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    INSERT		dbo.monAutreTable
    SELECT		F.sub_string_1
    		, F.sub_string_2
    		, F.sub_string_3
    		, F.sub_string_4
    		, F.sub_string_5
    		, F.sub_string_6
    FROM		dbo.import AS I
    CROSS APPLY	dbo.Fn_ParseTilde(I.string) AS F
    @++

  3. #3
    Membre du Club
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Janvier 2003
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Janvier 2003
    Messages : 85
    Points : 51
    Points
    51
    Par défaut
    Bonsoir,
    Je te remercie d'avoir répondu rapidement. Mais j'ai loupé un épisode. Je suis débutant avec SQLServer. Les fonctions je ne connait pas encore.
    J'ai recopié la fonction, j'ai exécuté et elle s'est crée dans la base. mais par contre je ne comprend pas la suite. Mon champ GQD_REFAFFECTATION est dans une table appelé DISPODETAIL. Comment utilisé la fonction dans un select pour récupérer les 6 champs.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    SELECT GQD_REFAFFECTATION, X1,X2,X3,X4,X5,X6 FROM DISPODETAIL
    Merci.

  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 : 43
    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
    Mon champ GQD_REFAFFECTATION est dans une table appelé DISPODETAIL
    OK, j'ai cru que la table s'appelle GQD_REFAFFECTATION.
    Au passage, dans une base de données relationnelle SQL, il n'y a pas de champ : il y a des colonnes

    Pour retourner les colonnes de la table produite par la fonction, j'ai utilisé l'opérateur CROSS APPLY.
    Votre requête devrait donc être :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    SELECT		D.REFAFFECTATION
    		, F.sub_string_1
    		, F.sub_string_2
    		, F.sub_string_3
    		, F.sub_string_4
    		, F.sub_string_5
    		, F.sub_string_6
    FROM		dbo.DISPODETAIL AS D
    CROSS APPLY	dbo.Fn_ParseTilde(D.REFAFFECTATION) AS F
    Vous ne pouvez pas donner directement le nom des colonnes de la table retournée par la fonction sans la spécifier dans votre requête

    @++

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

    En sus de la solution proposée par Elsuket, voici une autre solution qui se base sur les fonctionx XML nodes() et query() :

    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
    DECLARE @t TABLE
    (
     col VARCHAR(500)
    )
     
    INSERT INTO @t VALUES ('GL~CC~GCC~1075~0~1');
    INSERT INTO @t VALUES ('GL~CC~GCC~161~0~1');
    INSERT INTO @t VALUES ('GL~CC~GCC~161~0~2');
    INSERT INTO @t VALUES ('GL~CC~GCC~61~0~1');
    INSERT INTO @t VALUES ('GL~CC~GCC~61~0~111');
    INSERT INTO @t VALUES ('WOB~FAB~1360~110~18000');
    INSERT INTO @t VALUES ('WOB~FAB~1410~110~178000');
    INSERT INTO @t VALUES ('WOB~FAB~782~110~32000');
    INSERT INTO @t VALUES ('WOB~FAB~836~110~2000');
    INSERT INTO @t VALUES ('WOB~FAB~88~110~24000');
    INSERT INTO @t VALUES ('WOB~FAB~1847~110~102000');
    INSERT INTO @t VALUES ('WOB~FAB~849~1100~124000');
    INSERT INTO @t VALUES ('WOB~FAB~849~110~124000');
     
    WITH CTE
    AS
    (
     SELECT 
      ROW_NUMBER() OVER (ORDER BY (SELECT 0)) AS num,
      CAST('<a>' + REPLACE(col, '~', '</a><a>') + '</a>' AS XML) AS col_xml
     FROM @t
    ),
    CTE2
    AS
    (
     SELECT 
       num,
       ROW_NUMBER() OVER (PARTITION BY num ORDER BY (SELECT 0)) AS num2,
       CAST(node.query('./text()') AS VARCHAR(10)) AS valeur
      FROM CTE
     CROSS APPLY col_xml.nodes('/a') AS tmp (node)
    )
     
    SELECT 
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 1) AS col1,
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 2) AS col2,
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 3) AS col3,
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 4) AS col4,
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 5) AS col5,
     (SELECT valeur FROM CTE2 AS T2 WHERE T2.num = T.num AND T2.num2 = 6) AS col6
    FROM CTE2 AS T
    GROUP BY T.num;
    ++

  6. #6
    Membre du Club
    Homme Profil pro
    Conseil - Consultant en systèmes d'information
    Inscrit en
    Janvier 2003
    Messages
    85
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Tarn et Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Conseil - Consultant en systèmes d'information

    Informations forums :
    Inscription : Janvier 2003
    Messages : 85
    Points : 51
    Points
    51
    Par défaut Merci
    Bonjour
    et Merci pour toutes ces réponses.

    Voici un lien pour une super réponse : http://www.developpez.net/forums/d86...ee-separateur/

Discussions similaires

  1. extraire une sous-chaine d'un chaine
    Par mamax29 dans le forum Langage
    Réponses: 2
    Dernier message: 23/02/2011, 16h39
  2. [RegEx] Savoir si une chaine contient sous-chaine
    Par astrolane dans le forum Langage
    Réponses: 2
    Dernier message: 01/09/2009, 16h53
  3. parse une chaine en sous chaine de longueur max X
    Par bruman dans le forum Langage
    Réponses: 2
    Dernier message: 21/07/2008, 17h12
  4. Rechercher une sous chaine dans un chaine
    Par franck06 dans le forum Access
    Réponses: 2
    Dernier message: 20/09/2006, 14h53
  5. Séparer une chaine en sous chaine
    Par firemax dans le forum C
    Réponses: 9
    Dernier message: 03/06/2005, 12h23

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