Gibt es eine einfache Möglichkeit, den Index des letzten Auftretens einer Zeichenfolge mithilfe von SQL zu ermitteln? Ich verwende gerade SQL Server 2000. Ich brauche grundsätzlich die Funktionalität, die die .NET- System.String.LastIndexOf
Methode bietet. Ein wenig googeln ergab dies - Funktion zum Abrufen des letzten Index -, aber das funktioniert nicht, wenn Sie einen Spaltenausdruck "Text" übergeben. Andere an anderer Stelle gefundene Lösungen funktionieren nur, solange der gesuchte Text 1 Zeichen lang ist.
Ich werde wahrscheinlich eine Funktion erfinden müssen. Wenn ich das tue, werde ich es hier posten, damit ihr es euch ansehen und vielleicht nutzen könnt.
DATALENGTH
die Anzahl der Bytes und nicht der Zeichen zurück. Gibt daherDATALENGTH
2 x die Anzahl der Zeichen in einer Zeichenfolge fürNVARCHAR
Zeichenfolgen zurück.LEN
Gibt jedoch die Anzahl der Zeichen abzüglich aller nachgestellten Leerzeichen zurück . Ich verwende es nieDATALENGTH
für die Berechnung derVARCHAR
NVARCHAR
Einfacher Weg? Nein, aber ich habe das Gegenteil verwendet. Buchstäblich.
In früheren Routinen habe ich, um das letzte Vorkommen einer bestimmten Zeichenfolge zu ermitteln, die Funktion REVERSE () verwendet, gefolgt von CHARINDEX, gefolgt von REVERSE, um die ursprüngliche Reihenfolge wiederherzustellen. Zum Beispiel:
zeigt, wie die tatsächlichen Datenbankdateinamen aus ihren "physischen Namen" extrahiert werden, unabhängig davon, wie tief sie in Unterordnern verschachtelt sind. Dies sucht zwar nur nach einem Zeichen (dem Backslash), aber Sie können darauf für längere Suchzeichenfolgen aufbauen.
Der einzige Nachteil ist, ich weiß nicht, wie gut dies bei TEXT-Datentypen funktioniert. Ich bin jetzt seit ein paar Jahren in SQL 2005 und bin nicht mehr mit der Arbeit mit TEXT vertraut - aber ich erinnere mich, dass Sie LEFT und RIGHT verwenden können?
Philip
quelle
Der einfachste Weg ist ....
quelle
[expr]
Symbol länger als 1 ist, müssen Sie es auch umkehren!Wenn Sie Sqlserver 2005 oder höher verwenden, wirkt sich die
REVERSE
mehrfache Verwendung der Funktion nachteilig auf die Leistung aus. Der folgende Code ist effizienter.quelle
quelle
Alte, aber immer noch gültige Frage, also hier ist, was ich basierend auf den Informationen erstellt habe, die von anderen hier bereitgestellt wurden.
quelle
Das hat bei mir sehr gut funktioniert.
quelle
hat besser für mich gearbeitet
quelle
Hmm, ich weiß, dass dies ein alter Thread ist, aber eine Tally-Tabelle könnte dies in SQL2000 (oder einer anderen Datenbank) tun:
Eine Tally-Tabelle ist nur eine Tabelle mit inkrementierenden Zahlen.
Das
substring(@str, _Tally.n, 1) = @delim
erhält die Position jedes Trennzeichens, dann erhalten Sie nur die maximale Position in diesem Satz.Tally Tische sind fantastisch. Wenn Sie sie noch nicht verwendet haben, gibt es einen guten Artikel über SQL Server Central (Free reg, oder verwenden Sie einfach Bug Me Not ( http://www.bugmenot.com/view/sqlservercentral.com )).
* EDIT: Entfernt
n <= LEN(TEXT_FIELD)
, da Sie LEN () nicht für den TEXT-Typ verwenden können. Solange dassubstring(...) = @delim
bleibt, ist das Ergebnis immer noch korrekt.quelle
Kehren Sie sowohl Ihren String als auch Ihren Teilstring um und suchen Sie dann nach dem ersten Vorkommen.
quelle
Einige der anderen Antworten geben eine tatsächliche Zeichenfolge zurück, während ich den tatsächlichen Index int besser kennen musste. Und die Antworten, die das tun, scheinen die Dinge zu komplizieren. Ich habe einige der anderen Antworten als Inspiration verwendet und Folgendes getan ...
Zuerst habe ich eine Funktion erstellt:
Dann können Sie in Ihrer Abfrage einfach Folgendes tun:
Das obige sollte 23 zurückgeben (der letzte Index von ':')
Hoffe das hat es jemandem etwas leichter gemacht!
quelle
Mir ist klar, dass dies eine mehrere Jahre alte Frage ist, aber ...
Ein
Access 2010
können Sie dazu verwendenInStrRev()
. Hoffe das hilft.quelle
Diese Antwort verwendet MS SQL Server 2008 (ich habe keinen Zugriff auf MS SQL Server 2000), aber die Art und Weise, wie ich es laut OP sehe, sind drei Situationen, die berücksichtigt werden müssen. Nach dem, was ich versucht habe, deckt hier keine Antwort alle drei ab:
0
Die Funktion, die ich mir ausgedacht habe, benötigt zwei Parameter:
@String NVARCHAR(MAX)
: Die zu durchsuchende Zeichenfolge@FindString NVARCHAR(MAX)
: Entweder ein einzelnes Zeichen oder eine Unterzeichenfolge, um den letzten Index von in zu erhalten@String
Es wird ein Wert zurückgegeben
INT
, der entweder der positive Index von@FindString
in ist@String
oder dies0
bedeutet@FindString
die nicht in ist@String
Hier ist eine Erklärung, was die Funktion tut:
@ReturnVal
um anzuzeigen ,0
dass dies@FindString
nicht der Fall ist@String
@FindString
In@String
mitCHARINDEX()
@FindString
in@String
ist0
,@ReturnVal
bleibt als0
@FindString
in@String
ist> 0
,@FindString
in ist ,@String
so dass es den letzten Index berechnet@FindString
in@String
unter Verwendung vonREVERSE()
@ReturnVal
entweder eine positive Zahl zurück, die der letzte Index von@FindString
in ist,@String
oder gibt an0
, dass@FindString
nicht in ist@String
Hier ist das Skript zum Erstellen von Funktionen (fertig zum Kopieren und Einfügen):
Hier ist ein kleines bisschen, das die Funktion bequem testet:
Ich habe dies nur unter MS SQL Server 2008 ausgeführt, da ich keinen Zugriff auf eine andere Version habe, aber von dem, was ich mir angesehen habe, sollte dies zumindest für 2008+ gut sein.
Genießen.
quelle
Ich weiß, dass es ineffizient sein wird, aber haben Sie darüber nachgedacht, das
text
Feld zuvarchar
besetzen, damit Sie die Lösung verwenden können, die von der von Ihnen gefundenen Website bereitgestellt wird? Ich weiß, dass diese Lösung Probleme verursachen würde, da Sie den Datensatz möglicherweise abschneiden könnten, wenn die Länge imtext
Feld die Länge Ihres Datensatzes überschreitetvarchar
(ganz zu schweigen davon, dass dies nicht sehr leistungsfähig wäre).Da sich Ihre Daten in einem
text
Feld befinden (und Sie SQL Server 2000 verwenden), sind Ihre Optionen begrenzt.quelle
Wenn Sie den Index des letzten Leerzeichens in einer Wortfolge abrufen möchten, können Sie diesen Ausdruck RIGHT (name, (CHARINDEX ('', REVERSE (name), 0)) verwenden, um das letzte Wort in der Zeichenfolge zurückzugeben ist hilfreich, wenn Sie den Nachnamen eines vollständigen Namens analysieren möchten, der Initialen für den Vor- und / oder Zweitnamen enthält.
quelle
@indexOf = <whatever characters you are searching for in your string>
@LastIndexOf = LEN([MyField]) - CHARINDEX(@indexOf, REVERSE([MyField]))
Nicht getestet, es kann sein, dass es wegen des Nullindex um eins abweicht, funktioniert aber in
SUBSTRING
Funktion, wenn Sie von@indexOf
Zeichen bis zum Ende Ihrer Zeichenfolge abhackenSUBSTRING([MyField], 0, @LastIndexOf)
quelle
Dieser Code funktioniert auch dann, wenn der Teilstring mehr als 1 Zeichen enthält.
quelle
Ich musste die n-te letzte Position eines Backslashs in einem Ordnerpfad finden. Hier ist meine Lösung.
Hier sind meine Testfälle, die bestehen
quelle
So erhalten Sie das Teil vor dem letzten Auftreten des Trennzeichens (funktioniert nur
NVARCHAR
aufgrund derDATALENGTH
Verwendung):quelle
Diese Antwort entspricht den Anforderungen des OP. Insbesondere erlaubt es der Nadel, mehr als ein einzelnes Zeichen zu sein, und es erzeugt keinen Fehler, wenn die Nadel nicht im Heuhaufen gefunden wird. Es schien mir, dass die meisten (alle?) Der anderen Antworten diese Randfälle nicht behandelten. Darüber hinaus habe ich das Argument "Startposition" hinzugefügt, das von der nativen MS SQL Server CharIndex-Funktion bereitgestellt wird. Ich habe versucht, die Spezifikation für CharIndex genau zu spiegeln, außer von rechts nach links statt von links nach rechts zu verarbeiten. zB gebe ich null zurück, wenn entweder Nadel oder Heuhaufen null ist, und ich gebe Null zurück, wenn Nadel nicht im Heuhaufen gefunden wird. Eine Sache, die ich nicht umgehen konnte, ist, dass mit der eingebauten Funktion der dritte Parameter optional ist. Bei benutzerdefinierten SQL Server-Funktionen müssen alle Parameter im Aufruf angegeben werden, es sei denn, die Funktion wird mit "EXEC" aufgerufen. . Während der dritte Parameter in der Parameterliste enthalten sein muss, können Sie das Schlüsselwort "default" als Platzhalter dafür angeben, ohne ihm einen Wert zu geben (siehe Beispiele unten). Da es einfacher ist, den dritten Parameter aus dieser Funktion zu entfernen, wenn dies nicht gewünscht ist, als ihn bei Bedarf hinzuzufügen, habe ich ihn hier als Ausgangspunkt aufgenommen.
quelle
Ich bin auf diesen Thread gestoßen, als ich nach einer Lösung für mein ähnliches Problem gesucht habe, das genau die gleichen Anforderungen hatte, aber für eine andere Art von Datenbank war, der auch das fehlte
REVERSE
Funktion .In meinem Fall war dies für eine OpenEdge (Progress) -Datenbank, die eine etwas andere Syntax hat. Dies stellte
INSTR
mir die Funktion zur Verfügung, die die meisten von Oracle typisierten Datenbanken bieten .Also habe ich mir folgenden Code ausgedacht:
Für meine spezielle Situation (als OpenEdge (Progress) -Datenbank) führte dies jedoch nicht zum gewünschten Verhalten, da das Ersetzen des Zeichens durch ein leeres Zeichen dieselbe Länge wie die ursprüngliche Zeichenfolge ergab. Das macht für mich nicht viel Sinn, aber ich konnte das Problem mit dem folgenden Code umgehen:
Jetzt verstehe ich, dass dieser Code das Problem für T-SQL nicht lösen wird, da es keine Alternative zu der
INSTR
Funktion gibt, die das bietetOccurence
Eigenschaft .Um genau zu sein, füge ich den Code hinzu, der zum Erstellen dieser Skalarfunktion erforderlich ist, damit er auf die gleiche Weise wie in den obigen Beispielen verwendet werden kann.
Um das Offensichtliche zu vermeiden,
REVERSE
müssen Sie diese Skalarfunktion nicht erstellen , wenn die Funktion verfügbar ist, und Sie können einfach das gewünschte Ergebnis wie folgt erhalten:quelle