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 :

Utilisation d'expressions régulières dans une procédure stockée.


Sujet :

Développement SQL Server

  1. #1
    Membre régulier
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juillet 2007
    Messages
    109
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Juillet 2007
    Messages : 109
    Points : 83
    Points
    83
    Par défaut Utilisation d'expressions régulières dans une procédure stockée.
    Bonjour à tous,

    je dois trouver dans une table "clients" l'ensemble des correspondances existants à partir de données saisies sur un écran (n° tel, code_postal, etc).

    Comme les données qui alimentent cette table viennent de plusieurs applications (+/- récente) les règles de saisies ne sont hélas pas toutes les mêmes et je dois mettre suffisamment d'intelligence dans ma recherche de correspondances pour satisfaire la majorité des cas sans plomber les perfs.

    Ma table contient près de 2 millions d'enregistrements (ce qui n'aide pas).

    Exemple : Trouver les correspondances à partir d'un numéro de téléphone saisi. En saisissant l'un des numéros suivants, remonter les correspondances des clients avec un numéro dans la liste suivante.

    0123456789
    01.23.45.67.89
    01/23/45/67/89
    01 23 45 67 89
    01-23-45-67-89
    0033123456789

    Si possible également : +33(0)123456789

    J'ai essayer avec la fonction scalaire suivante en utilisant replace en enlevant les caractères suivants :
    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
    CREATEFUNCTION [dbo].[f_formater_telephone]
    (	
    	-- Add the parameters for the function here
    	@telephone varchar(max)
    )
    RETURNS varchar(max)
    AS
    BEGIN
     
    	-- Add the SELECT statement with parameter references here
     
    	SET @telephone=replace(@telephone,' ','')
    	SET @telephone=replace(@telephone,'-','')
    	SET @telephone=replace(@telephone,'/','')
    	SET @telephone=replace(@telephone,'.','')
    	SET @telephone=replace(@telephone,'\','')
    	SET @telephone=replace(@telephone,',','')
    	SET @telephone=replace(@telephone,'_','')
    	SET @telephone=replace(@telephone,':','')
    	SET @telephone=replace(@telephone,'''','')
    	return ltrim(rtrim(@telephone))
    END
    J'aurai également aimé enlever tous les caractères non numériques. Lettres, etc...

    Est il possible d'utiliser les expressions régulières en SQL uniquement ?
    Les perfs avec cette méthode sont... catastrophiques.

    Une petite aide ? Une orientation ?
    Je suis preneur de tout.

    Merci à vous.

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

    2 possibilités :

    - Les objets OLE Automation
    - Les fonctions SQL CLR

    ++

  3. #3
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Comment faites vous votre requêtes?

    Le principe est de formater votre paramètre de recherche avant de lancer celle-ci?

  4. #4
    Membre émérite

    Homme Profil pro
    Chargé de Développement et d'Analyse de données
    Inscrit en
    Mars 2010
    Messages
    1 278
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Chargé de Développement et d'Analyse de données
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2010
    Messages : 1 278
    Points : 2 856
    Points
    2 856

  5. #5
    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
    Citation Envoyé par LestoK Voir le message
    dois mettre suffisamment d'intelligence dans ma recherche de correspondances pour satisfaire la majorité des cas sans plomber les perfs.

    Ma table contient près de 2 millions d'enregistrements (ce qui n'aide pas).
    Je pense qu'il va falloir commencer par nettoyer les données. Sans cela, vous serez dans tous les cas obligé de scanner la totalité de la table soit les deux millions de lignes pour voir si l'une d'entre elle correspond...

    Idéalement, il faudrait ajouter des contraintes sur ce type de colonne (numéro de téléphone, ...) afin d'en unifier le format.
    Si cela engendre trop de modifications coté applications, vous pouvez peut être prévoir une fonction (éventuellement CLR) pour reformater les numéros saisis... à placer dans des triggers INSERT/UPDATE. Si vous voulez néanmoins conserver les numéros tels qu'ils ont été saisis, vous pouvez aussi ajouter une colonne calculée persistante que vous pouvez indexer.

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

    A partir de la fonction que j'ai donné ici, on peut écrire :

    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
    CREATE FUNCTION [dbo].[getPhoneNumber] (@string varchar(20))
    	RETURNS varchar(20)
    	WITH SCHEMABINDING 
    AS 
    BEGIN 
    	DECLARE @result VARCHAR(1024) 
    		, @i int
    		, @lgr int
    		, @char char(1) 
     
    	SELECT	@i = 1
    		, @lgr = LEN(@string)
    		, @result = '' 
     
    	WHILE @i <= @Lgr 
    	BEGIN 
    		SELECT @char = SUBSTRING(@string, @i, 1) 
     
    		IF ASCII(@char) BETWEEN 48 AND 57 
    		BEGIN 
    			SET @result = @result + @char 
    		END 
     
    		SET @i = @i + 1 
    	END
     
    	RETURN @result
    END
    En changeant encore un peu le code, on doit pouvoir obtenir ce que vous souhaitez.
    J'espère que vous n'êtes pas dans un cadre international, parce que sinon c'est plus compliqué : il vous faudra stocker les expressions des standards internationaux dans une petite table, et faire la comparaison.

    Normalement néanmoins, ce genre de corrections devrait être fait et vérifié au niveau de l'application

    Il suffit ensuite de s'en servir pour faire une colonne calculée :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    ALTER TABLE dbo.clients
    ADD correct_phone_number AS (dbo.getPhoneNumber(phone_number)) PERSISTED
    On peut ensuite indexer :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    CREATE INDEX IXNC_clients_correct_phone_number
    ON dbo.clients(correct_phone_number)
    @++

  7. #7
    Rédacteur

    Avatar de SQLpro
    Homme Profil pro
    Expert bases de données / SQL / MS SQL Server / Postgresql
    Inscrit en
    Mai 2002
    Messages
    21 902
    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 902
    Points : 53 143
    Points
    53 143
    Billets dans le blog
    6
    Par défaut
    C'est assez marrant car c'est un exemple que je donne dans mon cours d'optimisation à Orsys... En gros avec un REGEX on est à plus d'un millions de fois moins rapide sur un ensemble de ligne pas si délirant, par rapport à la colonne calculée persistante associée à une fonction de nettoyage.

    A +

  8. #8
    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
    En gros avec un REGEX on est à plus d'un millions de fois moins rapide sur un ensemble de ligne pas si délirant, par rapport à la colonne calculée persistante associée à une fonction de nettoyage.
    Un million ça me semble quand même assez gros !

    Mettons qu'on ait quelque chose de plus compliqué à faire : on implémente une fonction CLR, dont on se sert pour spécifier une colonne calculée que l'on indexe (pas obligé de la persister après tout !).

    Qu'en penses-tu ?

    @++

  9. #9
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 795
    Points : 3 173
    Points
    3 173
    Par défaut
    C'est assez marrant car c'est un exemple que je donne dans mon cours d'optimisation à Orsys... En gros avec un REGEX on est à plus d'un millions de fois moins rapide sur un ensemble de ligne pas si délirant, par rapport à la colonne calculée persistante associée à une fonction de nettoyage.
    Personnellement cela ne m'étonnes pas vraiment, même si un million peut paraître beaucoup.

    J'ai récemment refait un lot d'import de fichier plat en passant de 15 heures à... 20 secondes-> passage d'une approche full code client ADO.NET (vous auriez appriécié Frédéric ) en simple requète ensembliste.

  10. #10
    Membre expert Avatar de iberserk
    Homme Profil pro
    Architecte de base de données
    Inscrit en
    Novembre 2004
    Messages
    1 795
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    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 795
    Points : 3 173
    Points
    3 173
    Par défaut
    Mettons qu'on ait quelque chose de plus compliqué à faire : on implémente une fonction CLR, dont on se sert pour spécifier une colonne calculée que l'on indexe (pas obligé de la persister après tout !).
    Sauf que tu ne peux pas indexer une colonne calculée issue d'une fonction CLR sans la persister

Discussions similaires

  1. passage d'un nom de table dans une procédure stockée
    Par thierry V dans le forum MS SQL Server
    Réponses: 7
    Dernier message: 26/07/2010, 16h48
  2. Réponses: 1
    Dernier message: 12/12/2007, 13h46
  3. Réponses: 6
    Dernier message: 05/04/2007, 13h35
  4. [RegEx] Utiliser une expression régulière dans une requête
    Par Tobleron dans le forum Langage
    Réponses: 2
    Dernier message: 18/02/2007, 19h00
  5. Transformation de date dans une procédure stockée
    Par bd0606 dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 27/10/2003, 11h31

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