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

MS SQL Server Discussion :

decortiquer une parametre de type varchar


Sujet :

MS SQL Server

  1. #1
    Membre du Club
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    180
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France

    Informations forums :
    Inscription : Avril 2006
    Messages : 180
    Points : 61
    Points
    61
    Par défaut decortiquer une parametre de type varchar
    Bonjour,

    Je travaille sur sqlServer 2005. J'utilise des procédures stockées. Dans l'une de mes procédure stockée, j'ai une parametre @operation varchar(20).
    Exemple : "*0.24/F" ou "+0.36*H" ou "+23/56" ou "*1E-12/P". en générale mon parametre @operation doit commencer par un -+*/ ensuite on peut avoir des chaine de caratère et des doubles (1E-12 compris).

    Je souhaiterai récuperer toutes mes valeurs entre deux operator (/*-+) afin de les traiter.
    Comment pourrai-je faire je pensé utiliser les methodes charindex et substring mais je ne sais pas trop comment. Et je dois trouver la réponse pour aujourd'hui.

    Merci d'avance pour votre aide.

  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 : 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,

    Je vous propose la fonction table 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
    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
    ALTER FUNCTION [dbo].[Fn_Decortique](@operation VARCHAR(20))
    	RETURNS @Extraits TABLE(Extrait VARCHAR(20))
    AS
    BEGIN;
    	IF @operation IS NULL OR LEN(@operation) = 0
    		RETURN;
     
    	SET @operation = @operation + '|';
     
    	WITH
    		CTE_Indices AS
    		(
    				SELECT Symbole,
    						CHARINDEX(Symbole, @operation) AS Indice,
    						ROW_NUMBER() OVER(ORDER BY CHARINDEX(Symbole, @operation)) Ordre
    				FROM (
    						SELECT '/' Symbole
    						UNION SELECT '+'
    						UNION SELECT '-'
    						UNION SELECT '*'
    						UNION SELECT '|'
    					) TMP
    				WHERE CHARINDEX(Symbole, @operation) <> 0
     
    		),
    		CTE_Extraits AS
    		(
    			SELECT SUBSTRING(@operation, Deb.Indice + 1, Fin.Indice - Deb.Indice - 1) Extrait
    			FROM CTE_Indices Deb
    			JOIN CTE_Indices Fin ON Fin.Ordre = Deb.Ordre + 1
    		)
    	INSERT INTO @Extraits	
    	SELECT Extrait
    	FROM CTE_Extraits
    	WHERE LEN(Extrait) > 1
    	OR ISNUMERIC(Extrait) = 1
     
    	RETURN;
    END;
    J'ajoute le "|" au la chaîne en entrée pour pouvoir extraire ce qui se trouve après le dernier symbole contenu dans la chaîne.

    Les désavantages de cette fonction sont:

    - la faible performance des fonctions définies par l'utilisateur : cela ira bien si vous ne faites que passer une variable en paramètre, mais pas une colonne d'une table qui contient énormément de lignes,

    - elle contrôle la longueur de l'extrait qui doit être plus grande que 1 si l'extrait est une chaîne de caractères ('*AB/F' fonctionne mais pas '*B/F'), ou elle vérifie que les valeurs sont numériques dans les autres cas,

    - elle retourne une table de chaînes de caractères, donc si vous ne souhaitez traiter que des valeurs numériques, vous devrez les transtyper.
    Néanmoins si vous pouvez récupérer des décimaux et des entiers comme dans votre exemple, la table retournée aura une colonne de type NUMERIC, et devrez aussi transtyper pour traiter des entiers (INT).

    L'avantage de cette fonction est qu'elle retourne une table, donc que vous pouvez effectuer une jointure directement dessus, ou l'incorporer dans une expression de table commune pour le même but.

    A tester donc !

    @++

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

    Une version un peu plus compacte :

    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
    CREATE FUNCTION FnDecortique (@str VARCHAR(20))
    	RETURNS TABLE
    AS RETURN
    (
    	WITH CTE (Deb, Fin) AS
    	( 
    			SELECT 1 Deb, CHARINDEX('|', REPLACE(REPLACE(REPLACE(REPLACE(@str, '-', '|'), '+', '|'), '*', '|'), '/', '|') + '|') Fin 
    		UNION ALL 
    			SELECT Fin + 1, CHARINDEX('|', REPLACE(REPLACE(REPLACE(REPLACE(@str, '-', '|'), '+', '|'), '*', '|'), '/', '|') + '|', Fin + 1) 
    			FROM CTE 
    			WHERE CHARINDEX('|', REPLACE(REPLACE(REPLACE(REPLACE(@str, '-', '|'), '+', '|'), '*', '|'), '/', '|') + '|', Fin + 1 ) > 0 
    	) 
    	SELECT SUBSTRING(@str, Deb , Fin - Deb) Extrait
    	FROM CTE
    	WHERE Deb <> Fin
    	AND ISNUMERIC(SUBSTRING(REPLACE(REPLACE(REPLACE(REPLACE(@str, '-', '|'), '+', '|'), '*', '|'), '/', '|') + '|', Deb , Fin - Deb)) = 1
    	OR LEN(SUBSTRING(REPLACE(REPLACE(REPLACE(REPLACE(@str, '-', '|'), '+', '|'), '*', '|'), '/', '|') + '|', Deb , Fin - Deb)) > 1
    )
    Néanmoins, n'est-il pas possible de déplacer cette logique du côté de l'application ?

    @++

Discussions similaires

  1. Mise à jour d'une référence de type varchar vers type entier
    Par Mistraldor dans le forum Langage SQL
    Réponses: 5
    Dernier message: 21/07/2011, 09h53
  2. Recherche sur date avec une colonne de type varchar
    Par Cladjidane dans le forum Requêtes
    Réponses: 3
    Dernier message: 21/08/2008, 22h35
  3. récupérer le nom des champs d'une table de type VARCHAR
    Par melisse dans le forum Requêtes
    Réponses: 4
    Dernier message: 14/02/2008, 11h03
  4. compter les colonnes de type varchar d'une base
    Par jcachico dans le forum SQL Procédural
    Réponses: 2
    Dernier message: 18/07/2007, 12h10
  5. Réponses: 2
    Dernier message: 28/06/2007, 15h56

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