jeudi 11 mars 2010

SQL Server : compter le nombre d'occurrences dans une chaîne

Je profite de mon heure de dîner pour écrire mon billet d'aujourd'hui puisque je viens à l'instant de trouver ce truc très utile en Transact-SQL (T-SQL) pour SQL Server.

J'avais un texte dans lequel je voulais compter le nombre d'occurrences trouvées d'une autre chaîne. En regardant la documentation pour trouver une fonction built-in qui me permettrait de le faire, j'en suis venu à un constat que le nombre de fonctions disponibles est assez limité : il y aurait une possibilité de faire une boucle en utilisant CHARINDEX mais ce n'était pas l'idéal.

Sinon, il existe ce truc encore plus efficace et étonnamment simple :
DECLARE
@count integer,
@search varchar(10),
@long_string varchar(500)

SET @search = '18'
SET @long_string = 'code 18 code 18 code 18 code code code 18'

SET @count = (DATALENGTH(@long_string) - DATALENGTH(REPLACE(@long_string, @search, ''))) / DATALENGTH(@search)

SELECT @count
Il ne reste qu'à dissimuler ce snippet de code réutilisable dans une user defined function et à lui faire appel dans le contexte qui nous convient le mieux.

2 commentaires:

  1. Bonjour
    Eureka ! C'est exactement ce que j'ai besoin de faire mise à part que ma requête doit me retourner plusieurs résultats. J'ai donc tenté une adaptation :

    DECLARE
    @count integer,
    @search varchar(1),
    @long_string varchar(200)
    SET @search = '_'
    SET @long_string = (SELECT distinct [ses_CODSTAGE] FROM [dm_PRODUCTION].[vf_CA_HIHVHP] where [ses_CODSTAGE] is not null)
    SET @count = ((DATALENGTH(@long_string) - DATALENGTH(REPLACE(@long_string, @search, ''))) / DATALENGTH(@search)+1)

    SELECT @long_string, @count

    Mais j'ai le message d'erreur suivant :
    Subquery returned more than 1 value. This is not permitted when the subquery follows =, !=, <, <= , >, >= or when the subquery is used as an expression.
    Warning: Null value is eliminated by an aggregate or other SET operation.

    Pouvez-vous m'aider ?
    Merci

    RépondreEffacer