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:
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
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:
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
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 la Occurence
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.
-- Drop the function if it already exists
IF OBJECT_ID('INSTR', 'FN') IS NOT NULL
DROP FUNCTION INSTR
GO
-- User-defined function to implement Oracle INSTR in SQL Server
CREATE FUNCTION INSTR (@str VARCHAR(8000), @substr VARCHAR(255), @start INT, @occurrence INT)
RETURNS INT
AS
BEGIN
DECLARE @found INT = @occurrence,
@pos INT = @start;
WHILE 1=1
BEGIN
-- Find the next occurrence
SET @pos = CHARINDEX(@substr, @str, @pos);
-- Nothing found
IF @pos IS NULL OR @pos = 0
RETURN @pos;
-- The required occurrence found
IF @found = 1
BREAK;
-- Prepare to find another one occurrence
SET @found = @found - 1;
SET @pos = @pos + 1;
END
RETURN @pos;
END
GO
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:
SELECT
LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo