Existe-t-il un moyen simple de trouver l'index de la dernière occurrence d'une chaîne à l'aide de SQL? J'utilise actuellement SQL Server 2000. J'ai essentiellement besoin des fonctionnalités System.String.LastIndexOf
fournies par la méthode .NET . Un peu de googler a révélé ceci - Fonction pour récupérer le dernier index - mais cela ne fonctionne pas si vous passez dans une expression de colonne "texte". Les autres solutions trouvées ailleurs ne fonctionnent que tant que le texte que vous recherchez fait 1 caractère.
Je devrai probablement préparer une fonction. Si je le fais, je le posterai ici pour que vous puissiez le regarder et peut-être l'utiliser.
DATALENGTH
renvoie le nombre d'octets et non de caractères. Par conséquent,DATALENGTH
renvoie 2 x le nombre de caractères dans une chaîne pour lesNVARCHAR
chaînes.LEN
, cependant, renvoie le nombre de caractères, moins les espaces de fin . Je ne l'utilise jamaisDATALENGTH
pour le calcul de la longueur des caractères à moins que l'espace blanc de fin ne soit significatif et je sais avec certitude que mes types de données sont cohérents, qu'ils soientVARCHAR
ouNVARCHAR
Une manière simple? Non, mais j'ai utilisé l'inverse. Au sens propre.
Dans les routines précédentes, pour trouver la dernière occurrence d'une chaîne donnée, j'ai utilisé la fonction REVERSE (), suivie de CHARINDEX, suivie à nouveau de REVERSE pour restaurer l'ordre d'origine. Par exemple:
montre comment extraire les noms de fichiers réels de la base de données à partir de leurs "noms physiques", quelle que soit la profondeur de leur imbrication dans les sous-dossiers. Cela ne recherche qu'un seul caractère (la barre oblique inverse), mais vous pouvez utiliser cela pour des chaînes de recherche plus longues.
Le seul inconvénient est que je ne sais pas dans quelle mesure cela fonctionnera sur les types de données TEXT. Je suis sur SQL 2005 depuis quelques années maintenant, et je ne suis plus familier avec TEXT - mais il me semble que vous pourriez utiliser GAUCHE et DROITE dessus?
Philippe
la source
Le moyen le plus simple est ...
la source
[expr]
symbole dépasse 1 symbole, vous devez également l'inverser!Si vous utilisez Sqlserver 2005 ou supérieur, l'utilisation de la
REVERSE
fonction plusieurs fois est préjudiciable aux performances, le code ci-dessous est plus efficace.la source
la source
Question ancienne mais toujours valable, voici donc ce que j'ai créé sur la base des informations fournies par d'autres ici.
la source
Cela a très bien fonctionné pour moi.
la source
a mieux fonctionné pour moi
la source
Hmm, je sais que c'est un ancien thread, mais une table de pointage pourrait le faire dans SQL2000 (ou toute autre base de données):
Un tableau de pointage est juste un tableau de nombres incrémentiels.
Le
substring(@str, _Tally.n, 1) = @delim
obtient la position de chaque délimiteur, puis vous obtenez simplement la position maximale dans cet ensemble.Les tableaux de pointage sont géniaux. Si vous ne les avez pas encore utilisés, il existe un bon article sur SQL Server Central (Free reg, ou utilisez simplement Bug Me Not ( http://www.bugmenot.com/view/sqlservercentral.com )).
* EDIT: Supprimé
n <= LEN(TEXT_FIELD)
, car vous ne pouvez pas utiliser LEN () sur le type TEXT. Tant que lesubstring(...) = @delim
reste, le résultat est toujours correct.la source
Inversez à la fois votre chaîne et votre sous-chaîne, puis recherchez la première occurrence.
la source
Certaines des autres réponses renvoient une chaîne réelle alors que j'avais plus besoin de connaître l'index réel int. Et les réponses qui font cela semblent trop compliquer les choses. En utilisant certaines des autres réponses comme source d'inspiration, j'ai fait ce qui suit ...
Tout d'abord, j'ai créé une fonction:
Ensuite, dans votre requête, vous pouvez simplement faire ceci:
Ce qui précède doit renvoyer 23 (le dernier index de ':')
J'espère que cela a rendu les choses un peu plus faciles pour quelqu'un!
la source
Je me rends compte que c'est une question vieille de plusieurs années, mais ...
Sur
Access 2010
, vous pouvez utiliserInStrRev()
pour le faire. J'espère que cela t'aides.la source
Cette réponse utilise MS SQL Server 2008 (je n'ai pas accès à MS SQL Server 2000), mais la façon dont je la vois selon l'OP sont 3 situations à prendre en compte. D'après ce que j'ai essayé, aucune réponse ne couvre les 3:
0
La fonction que j'ai créée prend 2 paramètres:
@String NVARCHAR(MAX)
: La chaîne à rechercher@FindString NVARCHAR(MAX)
: Soit un seul caractère, soit une sous-chaîne pour obtenir le dernier index de@String
Il renvoie un
INT
qui est soit l'indice positif de@FindString
in,@String
soit la0
signification qui@FindString
n'est pas dans@String
Voici une explication de ce que fait la fonction:
@ReturnVal
pour0
indiquer que ce@FindString
n'est pas@String
@FindString
in@String
en utilisantCHARINDEX()
@FindString
in@String
est0
,@ReturnVal
est laissé comme0
@FindString
in@String
est> 0
,@FindString
is in@String
, il calcule le dernier index de@FindString
in@String
en utilisantREVERSE()
@ReturnVal
un nombre positif qui est le dernier index de@FindString
in@String
ou0
indiquant qu'il@FindString
n'est pas dans@String
Voici le script de création de la fonction (prêt pour le copier-coller):
Voici un petit peu qui teste commodément la fonction:
Je n'ai exécuté cela que sur MS SQL Server 2008 parce que je n'ai accès à aucune autre version, mais d'après ce que j'ai examiné, cela devrait être bon pour 2008+ au moins.
Prendre plaisir.
la source
Je sais que ce sera inefficace mais avez-vous envisagé de convertir le
text
champ pourvarchar
pouvoir utiliser la solution fournie par le site Web que vous avez trouvé? Je sais que cette solution créerait des problèmes car vous pourriez potentiellement tronquer l'enregistrement si la longueur dutext
champ dépassait la longueur de votrevarchar
(pour ne pas mentionner qu'il ne serait pas très performant).Étant donné que vos données se
text
trouvent dans un champ (et que vous utilisez SQL Server 2000), vos options sont limitées.la source
Si vous souhaitez obtenir l'index du dernier espace dans une chaîne de mots, vous pouvez utiliser cette expression RIGHT (nom, (CHARINDEX ('', REVERSE (nom), 0)) pour renvoyer le dernier mot de la chaîne. est utile si vous souhaitez analyser le nom de famille d'un nom complet qui inclut les initiales du prénom et / ou du deuxième prénom.
la source
@indexOf = <whatever characters you are searching for in your string>
@LastIndexOf = LEN([MyField]) - CHARINDEX(@indexOf, REVERSE([MyField]))
Je n'ai pas testé, il peut être désactivé de un à cause de l'index zéro, mais fonctionne en
SUBSTRING
fonction lors du découpage des@indexOf
caractères à la fin de votre chaîneSUBSTRING([MyField], 0, @LastIndexOf)
la source
Ce code fonctionne même si la sous-chaîne contient plus d'un caractère.
la source
J'avais besoin de trouver la nième dernière position d'une barre oblique inverse dans le chemin d'un dossier. Voici ma solution.
Voici mes cas de test qui passent
la source
Pour obtenir la partie avant la dernière occurrence du délimiteur (fonctionne uniquement en
NVARCHAR
raison de l'DATALENGTH
utilisation):la source
Cette réponse répond aux exigences du PO. spécifiquement, il permet à l'aiguille d'être plus d'un seul caractère et il ne génère pas d'erreur lorsque l'aiguille n'est pas trouvée dans la botte de foin. Il me semblait que la plupart (toutes?) Des autres réponses ne traitaient pas ces cas extrêmes. Au-delà, j'ai ajouté l'argument "Position de départ" fourni par la fonction CharIndex native du serveur MS SQL. J'ai essayé de refléter exactement la spécification de CharIndex, sauf pour traiter de droite à gauche au lieu de gauche à droite. par exemple, je renvoie null si aiguille ou meule de foin est nulle et je renvoie zéro si l'aiguille n'est pas trouvée dans la meule de foin. Une chose que je ne pouvais pas contourner est qu'avec la fonction intégrée, le troisième paramètre est facultatif. Avec les fonctions définies par l'utilisateur SQL Server, tous les paramètres doivent être fournis dans l'appel sauf si la fonction est appelée à l'aide de "EXEC" . Alors que le troisième paramètre doit être inclus dans la liste des paramètres, vous pouvez lui fournir le mot-clé "default" comme espace réservé sans avoir à lui donner une valeur (voir les exemples ci-dessous). Puisqu'il est plus facile de supprimer le troisième paramètre de cette fonction s'il n'est pas souhaité que de l'ajouter si nécessaire, je l'ai inclus ici comme point de départ.
la source
Je suis tombé sur ce fil en cherchant une solution à mon problème similaire qui avait exactement la même exigence mais qui concernait un type de base de données différent qui manquait également de
REVERSE
fonction.Dans mon cas, c'était pour une base de données OpenEdge (Progress) , qui a une syntaxe légèrement différente. Cela
INSTR
m'a rendu disponible la fonction que la plupart des bases de données typées Oracle offrent .Je suis donc venu avec le code suivant:
Cependant, pour ma situation spécifique (étant la base de données OpenEdge (Progress) ), cela n'a pas abouti au comportement souhaité car le remplacement du caractère par un caractère vide a donné la même longueur que la chaîne d'origine. Cela n'a pas beaucoup de sens pour moi, mais j'ai pu contourner le problème avec le code ci-dessous:
Maintenant, je comprends que ce code ne résoudra pas le problème pour T-SQL car il n'y a pas d'alternative à la
INSTR
fonction qui offre laOccurence
propriété.Juste pour être complet, j'ajouterai le code nécessaire pour créer cette fonction scalaire afin qu'elle puisse être utilisée de la même manière que je l'ai fait dans les exemples ci-dessus.
Pour éviter l'évidence, lorsque la
REVERSE
fonction est disponible, vous n'avez pas besoin de créer cette fonction scalaire et vous pouvez simplement obtenir le résultat requis comme ceci:la source