Précédent   Forum des professionnels en informatique > Bases de données > MS SQL-Server > Développement
Développement Forum d'entraide sur le Transact-SQL, le CLR, les procédures stockées, les triggers, les requêtes SQL
Partagez cette discussion sur d'autres réseaux sociaux : Viadeo Twitter Google Facebook Digg Delicious MySpace Yahoo
Réponse Proposer ce sujet en actualité
 
Outils de la discussion
Publicité
'
Vieux 26/05/2011, 17h03   #1
Membre du Club
 
Homme Jérôme
Ingénieur développement logiciels
Inscription : juillet 2007
Messages : 109
Détails du profil
Informations personnelles :
Nom : Homme Jérôme
Âge : 26
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 : 54
Points : 54
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 :
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.
LestoK est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 26/05/2011, 20h06   #2
Responsable SQL Server

 
Avatar de mikedavem
 
Homme David BARBARIN
Expert SQL Server
Inscription : août 2005
Messages : 3 723
Détails du profil
Informations personnelles :
Nom : Homme David BARBARIN
Localisation : France, Haute Savoie (Rhône Alpes)

Informations professionnelles :
Activité : Expert SQL Server
Secteur : Conseil

Informations forums :
Inscription : août 2005
Messages : 3 723
Points : 6 844
Points : 6 844
Bonsoir,

2 possibilités :

- Les objets OLE Automation
- Les fonctions SQL CLR

++
mikedavem est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/05/2011, 08h35   #3
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Comment faites vous votre requêtes?

Le principe est de formater votre paramètre de recherche avant de lancer celle-ci?
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/05/2011, 09h55   #4
Membre Expert
 
Homme Etienne ZINZINDOHOUE
Ingénieur développement
Inscription : mars 2010
Messages : 1 139
Détails du profil
Informations personnelles :
Nom : Homme Etienne ZINZINDOHOUE
Localisation : France, Nord (Nord Pas de Calais)

Informations professionnelles :
Activité : Ingénieur développement
Secteur : High Tech - Opérateur de télécommunications

Informations forums :
Inscription : mars 2010
Messages : 1 139
Points : 2 467
Points : 2 467
Envoyer un message via Yahoo à zinzineti
Tu peux lire ceci
__________________
Etienne ZINZINDOHOUE
Billets-Articles
zinzineti est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/05/2011, 10h00   #5
Membre Expert
 
Inscription : janvier 2010
Messages : 1 084
Détails du profil
Informations personnelles :
Localisation : France, Rhône (Rhône Alpes)

Informations forums :
Inscription : janvier 2010
Messages : 1 084
Points : 1 573
Points : 1 573
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.
aieeeuuuuu est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 27/05/2011, 11h10   #6
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Bonjour,

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

Code :
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 :
1
2
ALTER TABLE dbo.clients
ADD correct_phone_number AS (dbo.getPhoneNumber(phone_number)) PERSISTED
On peut ensuite indexer :

Code :
1
2
CREATE INDEX IXNC_clients_correct_phone_number
ON dbo.clients(correct_phone_number)
@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/05/2011, 00h18   #7
Rédacteur/Modérateur

 
Avatar de SQLpro
 
Homme Frédéric BROUARD
Expert SGBDR & SQL
Inscription : mai 2002
Messages : 10 953
Détails du profil
Informations personnelles :
Nom : Homme Frédéric BROUARD
Localisation : France

Informations professionnelles :
Activité : Expert SGBDR & SQL
Secteur : Conseil

Informations forums :
Inscription : mai 2002
Messages : 10 953
Points : 17 773
Points : 17 773
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 +
__________________
Frédéric Brouard - SQLpro - ARCHITECTE DE DONNÉES - expert SGBDR et langage SQL
Site sur les SGBD relationnels et le langage SQL: http://sqlpro.developpez.com/
Expert Microsoft SQL Server - M.V.P. (Most valuable Professional) MS Corp.
Blog SQL, SQL Server, modélisation données : http://blog.developpez.com/sqlpro
http://www.sqlspot.com : modélisation, conseils, audit, optimisation, formation
* * * * * Enseignant CNAM PACA - ISEN Toulon - CESI Aix en Provence * * * * *
SQLpro est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/05/2011, 12h50   #8
Modérateur

 
Avatar de elsuket
 
Homme Nicolas Souquet
Administrateur de base de données
Inscription : janvier 2005
Messages : 4 669
Détails du profil
Informations personnelles :
Nom : Homme Nicolas Souquet
Âge : 30
Localisation : Thaïlande

Informations professionnelles :
Activité : Administrateur de base de données
Secteur : High Tech - Éditeur de logiciels

Informations forums :
Inscription : janvier 2005
Messages : 4 669
Points : 8 729
Points : 8 729
Citation:
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 ?

@++
__________________
En bases de données relationnelles SQL, il n'y a ni tableaux, ni enregistrements, ni champs: il y a des tables, des lignes et des colonnes.
Blog | Profil| Consulter ou télécharger les fichiers d'aide de SQL Server, des versions 2000 à 2012
elsuket est déconnecté   Envoyer un message privé Réponse avec citation 00
Vieux 28/05/2011, 15h41   #9
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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.
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 10
Vieux 28/05/2011, 15h47   #10
Membre Expert
 
Avatar de iberserk
 
Homme Bruno IGNACE
Architecte de base de données
Inscription : novembre 2004
Messages : 1 299
Détails du profil
Informations personnelles :
Nom : Homme Bruno IGNACE
Âge : 30
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 299
Points : 2 282
Points : 2 282
Envoyer un message via MSN à iberserk
Citation:
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
__________________
Prendre conscience, c'est transformer le voile qui recouvre la lumière en miroir.
iberserk est déconnecté   Envoyer un message privé Réponse avec citation 00
Réponse Proposer ce sujet en actualité
Outils de la discussion



Fuseau horaire GMT +2. Il est actuellement 16h54.


 
 
 
 
Partenaires

Hébergement Web