Afin de compléter cet article sur la recherche de motifs (rapprochement de chaines de caractères), voici une version qui gère la casse et les accents.
CREATE FUNCTION dbo.F_INFERENCE_BASIQUE (@SOURCE VARCHAR(8000),
@CIBLE VARCHAR(8000),
@CS BIT,
@AS BIT )
RETURNS FLOAT
AS
/******************************************************************************
* Fonction de calcul de rapprochement entre deux chaines de caractères *
*******************************************************************************
* Fred. Brouard - http://sqlpro.developpez.com - www.sqlspot.com - 2009-10-26 *
*******************************************************************************
* donne un indice de rapprochement etre deux chaines pour comparaison avec *
* différentes occurrences *
* @SOURCE est la chaine source *
* @CIBLE est la chaine cible *
* Si @CS vaut 1 alors la comparaison est sensible à la casse *
* Si @AS vaut 1 alors la comparaison est sensible aux caractères diacritiques *
* (accents, cédille....) *
******************************************************************************/
BEGIN
IF @SOURCE IS NULL OR @CIBLE IS NULL RETURN NULL;
IF @SOURCE = '' OR @CIBLE = '' RETURN 0;
SET @CS = COALESCE(@CS, 0);
SET @AS = COALESCE(@AS, 0);
DECLARE @COUNT1 INT, @COUNT2 INT
DECLARE @I INT, @J INT, @L INT
DECLARE @C CHAR(1), @X INT
SET @COUNT1 = 0
SET @COUNT2 = 0
SET @I = 1
SET @J = 1
SET @L = LEN(@SOURCE)
-- première passe source vers cible
WHILE @I <= @L
BEGIN
SET @C = SUBSTRING(@SOURCE, @I, 1)
SET @X = CASE
WHEN @CS = 1 AND @AS = 1
THEN CHARINDEX(@C COLLATE French_CS_AS, @CIBLE COLLATE French_CS_AS, @J)
WHEN @CS = 1 AND @AS = 0
THEN CHARINDEX(@C COLLATE French_CS_AI, @CIBLE COLLATE French_CS_AI, @J)
WHEN @CS = 0 AND @AS = 1
THEN CHARINDEX(@C COLLATE French_CI_AS, @CIBLE COLLATE French_CI_AS, @J)
WHEN @CS = 0 AND @AS = 0
THEN CHARINDEX(@C COLLATE French_CI_AI, @CIBLE COLLATE French_CI_AI, @J)
END;
IF @X > 0
BEGIN
SET @COUNT1 = @COUNT1 + 1
SET @J = @X + 1
SET @I = @I + 1
CONTINUE
END
SET @I = @I + 1
END
IF @COUNT1 = 0 RETURN 0
SET @I = 1
SET @J = 1
SET @L = LEN(@CIBLE)
-- seconde passe cible vers source
WHILE @I <= @L
BEGIN
SET @C = SUBSTRING(@CIBLE, @I, 1)
SET @X = CASE
WHEN @CS = 1 AND @AS = 1
THEN CHARINDEX(@C COLLATE French_CS_AS, @SOURCE COLLATE French_CS_AS, @J)
WHEN @CS = 1 AND @AS = 0
THEN CHARINDEX(@C COLLATE French_CS_AI, @SOURCE COLLATE French_CS_AI, @J)
WHEN @CS = 0 AND @AS = 1
THEN CHARINDEX(@C COLLATE French_CI_AS, @SOURCE COLLATE French_CI_AS, @J)
WHEN @CS = 0 AND @AS = 0
THEN CHARINDEX(@C COLLATE French_CI_AI, @SOURCE COLLATE French_CI_AI, @J)
END;
IF @X > 0
BEGIN
SET @COUNT2 = @COUNT2 + 1
SET @J = @X + 1
SET @I = @I + 1
CONTINUE
END
SET @I = @I + 1
END
RETURN CAST(CASE WHEN @COUNT1 < @COUNT2 THEN @COUNT2 ELSE @COUNT1 END AS FLOAT)
/ CAST(CASE WHEN LEN(@SOURCE) < LEN(@CIBLE) THEN LEN(@CIBLE) ELSE LEN(@SOURCE) END AS FLOAT)
END
GO
—
Frédéric BROUARD, Spécialiste modélisation, bases de données, optimisation, langage SQL.
Le site sur le langage SQL et les S.G.B.D. relationnels : http://sqlpro.developpez.com/
Expert SQL Server http://www.sqlspot.com : audit, optimisation, tuning, formation
* * * * * Enseignant au CNAM PACA et à l’ISEN à Toulon * * * * *