declare @name nvarchar(max)
set @name ='ali reza dar yek shabe barani ba yek dokhtare khoshkel be disco raft va ali baraye 1 saat anja bud va sepas... ali...'
Declare @a table (pos int)
Declare @pos int
Declare @oldpos int
Select @oldpos=0
select @pos=patindex('%ali%',@name)
while @pos > 0 and @oldpos<>@pos
begin
insert into @a Values (@pos)
Select @oldpos=@pos
select @pos=patindex('%ali%',Substring(@name,@pos + 1,len(@name))) + @pos
end
Select * from @a
Pour le rendre réutilisable, vous pouvez l'utiliser dans une fonction de table pour l'appeler comme:
Select * from dbo.F_CountPats ('ali reza dar yek shabe barani ba yek dokhtare khoshkel be disco raft va ali baraye 1 saat anja bud va sepas... ali...','%ali%')
La fonction pourrait ressembler à ceci
Create FUNCTION [dbo].[F_CountPats]
(
@txt varchar(max),
@Pat varchar(max)
)
RETURNS
@tab TABLE
(
ID int
)
AS
BEGIN
Declare @pos int
Declare @oldpos int
Select @oldpos=0
select @pos=patindex(@pat,@txt)
while @pos > 0 and @oldpos<>@pos
begin
insert into @tab Values (@pos)
Select @oldpos=@pos
select @pos=patindex(@pat,Substring(@txt,@pos + 1,len(@txt))) + @pos
end
RETURN
END
GO
1
dans une chaîne qui ne contient que des zéros et des uns. J'ai utilisé votre solution et @ aaron-bertrand, mais j'ai obtenu les mêmes résultats et les mêmes performances. Quelle solution serait-il préférable?Je pense que ce sera légèrement plus efficace que la méthode de bouclage que vous avez choisie ( quelques preuves ici ), et certainement plus efficace que le CTE récursif:
Exemple d'utilisation:
Résultats:
Si vos chaînes seront plus longues que 2 Ko, utilisez sys.all_columns au lieu de sys.all_objects. Si plus de 8K, ajoutez une jointure croisée.
la source
- CTE récursif
la source
J'adore la réponse d'Aaron Bertrand. Bien que je ne le comprenne pas complètement, il a l'air vraiment élégant.
Dans le passé, j'ai rencontré des problèmes avec les autorisations lors de l'utilisation
sys.objects
. Combiné avec la nécessité pour moi de dépanner le code, j'ai trouvé une variante du code d'Aaron et je l'ai ajouté ci-dessous.Voici ma procédure:
La
MAX(posid)
valeur est également le nombre de correspondances trouvées.la source
Il s'agit d'un code simple basé sur la réponse d'Aaron qui:
CODE:
RÉSULTAT
la source
sys.all_columns
(vous pouvez utiliser n'importe quelle source tant qu'elle couvre la longueur de votre plus longue chaîne), et j'ai également re-testé et je ne vois pas où je manque le dernier «X» .. .Désolé les gars de venir si tard, mais j'aimerais rendre les choses plus faciles pour les gens qui veulent développer cela. Je regardais chacune de ces implémentations, j'ai pris celle qui me semblait la meilleure (Aaron Bertrand), je l'ai simplifiée et voilà, vous avez le "template". Fais-en bon usage.
Juste comme référence - vous pouvez en dériver d'autres comportements, comme développer PATINDEX ():
la source
la source