La petite fonction qui suit permet de compter le nombre de fois ou un caractère est présent dans une chaine de caractères.
CREATE FUNCTION F_COUNT_CHAR(@STR NVARCHAR(MAX), @CHR NCHAR(1))
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INT, @POS INT;
SELECT @NBR = 0, @POS = CHARINDEX(@CHR, @STR);
WHILE @POS > 0
BEGIN
SET @NBR = @NBR + 1;
SET @POS = CHARINDEX(@CHR, @STR, @POS + 1);
END;
RETURN @NBR;
END;
GO
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INT, @POS INT;
SELECT @NBR = 0, @POS = CHARINDEX(@CHR, @STR);
WHILE @POS > 0
BEGIN
SET @NBR = @NBR + 1;
SET @POS = CHARINDEX(@CHR, @STR, @POS + 1);
END;
RETURN @NBR;
END;
GO
Exemples d’utilisation :
-- exemple -- résultat
------------------------------------------- ------------
SELECT dbo.F_COUNT_CHAR('abracadabra', 'a') --> 5
SELECT dbo.F_COUNT_CHAR('', 'a') --> 0
SELECT dbo.F_COUNT_CHAR('a', '') --> 0
SELECT dbo.F_COUNT_CHAR('', '') --> 0
SELECT dbo.F_COUNT_CHAR(NULL, 'a') --> NULL
SELECT dbo.F_COUNT_CHAR('a', NULL) --> NULL
SELECT dbo.F_COUNT_CHAR(NULL, NULL) --> NULL
------------------------------------------- ------------
SELECT dbo.F_COUNT_CHAR('abracadabra', 'a') --> 5
SELECT dbo.F_COUNT_CHAR('', 'a') --> 0
SELECT dbo.F_COUNT_CHAR('a', '') --> 0
SELECT dbo.F_COUNT_CHAR('', '') --> 0
SELECT dbo.F_COUNT_CHAR(NULL, 'a') --> NULL
SELECT dbo.F_COUNT_CHAR('a', NULL) --> NULL
SELECT dbo.F_COUNT_CHAR(NULL, NULL) --> NULL
Frédéric Brouard, alias SQLpro, ARCHITECTE DE DONNÉES
Expert S.G.B.D relationnelles et langage S.Q.L
Moste Valuable Professionnal Microsoft SQL Server
Société SQLspot : modélisation, conseil, formation,
optimisation, audit, tuning, administration SGBDR
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.
Expert S.G.B.D relationnelles et langage S.Q.L
Moste Valuable Professionnal Microsoft SQL Server
Société SQLspot : modélisation, conseil, formation,
optimisation, audit, tuning, administration SGBDR
Enseignant: CNAM PACA, ISEN Toulon, CESI Aix en Prov.
L’entreprise SQL Spot
Le site web sur le SQL et les SGBDR
Aussi astucieuse soit-elle cette solution est moins rapide…
Voici mes tests :
la mienne rectifiée :
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INT, @POS INT;
SELECT @NBR = 0, @POS = CHARINDEX(@CHR, @STR);
WHILE @POS > 0
BEGIN
SET @NBR = @NBR + 1;
SET @POS = CHARINDEX(@CHR, @STR, @POS + LEN(@CHR));
END;
RETURN @NBR;
END;
GO
Sur 1 250 000 lignes : Temps UC = 4844 ms, temps écoulé = 6206 ms.
La vôtre rectifiée :
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INT, @STR2 NVARCHAR(MAX)
SELECT @NBR = IIF(LEN(ISNULL(@CHR,''))=0,0, (LEN(@STR)-LEN(REPLACE(@STR, @CHR,''))) / LEN(@CHR))
RETURN @NBR;
END;
GO
Sur le même panel de lignes : Temps UC = 6969 ms, temps écoulé = 8022 ms.
Bonjour,
Petite astuce : Plutôt que de faire une boucle, je fais plutôt ceci en une seule ligne.
A noter que cette fonction permet aussi le dénombrable d’une chaîne (@CHR peut faire plusieurs caractères). Et gère le cas où @CHR est nul ou de longueur nulle.
RETURNS INT
WITH RETURNS NULL ON NULL INPUT
AS
BEGIN
DECLARE @NBR INTn @STR2 NVARCHAR(MAX)
SELECT@NBR = IIF(LEN(ISNULL(@CHR,''))=0,0, (LEN(@STR)-LEN(REPLACE(@STR, @CHR,''))) / LEN(@CHR))
RETURN @NBR;
END;
GO