Encontré este hilo mientras buscaba una solución a mi problema similar que tenía exactamente el mismo requisito pero era para un tipo diferente de base de datos que también carecía de la REVERSE
función.
En mi caso, esto fue para una base de datos OpenEdge (Progress) , que tiene una sintaxis ligeramente diferente. Esto puso INSTR
a mi disposición la función que ofrecen la mayoría de las bases de datos escritas de Oracle .
Entonces se me ocurrió el siguiente código:
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
Sin embargo, para mi situación específica (que es la base de datos OpenEdge (Progress) ) esto no resultó en el comportamiento deseado porque reemplazar el carácter con un carácter vacío dio la misma longitud que la cadena original. Esto no tiene mucho sentido para mí, pero pude evitar el problema con el siguiente código:
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
Ahora entiendo que este código no resolverá el problema de T-SQL porque no hay alternativa a la INSTR
función que ofrece la Occurence
propiedad.
Solo para ser exhaustivo, agregaré el código necesario para crear esta función escalar para que pueda usarse de la misma manera que lo hice en los ejemplos anteriores.
-- 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
Para evitar lo obvio, cuando la REVERSE
función está disponible no necesita crear esta función escalar y simplemente puede obtener el resultado requerido de esta manera:
SELECT
LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo