Me deparei com esse segmento enquanto procurava uma solução para meu problema semelhante, que tinha exatamente o mesmo requisito, mas era para um tipo diferente de banco de dados que também não possuía o REVERSE
função.
No meu caso, isso era para um banco de dados OpenEdge (Progress) , que possui uma sintaxe um pouco diferente. Isso INSTR
disponibilizou para mim a função que a maioria dos bancos de dados digitados Oracle oferece .
Então, eu vim com o seguinte código:
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
No entanto, para minha situação específica (sendo o banco de dados OpenEdge (Progress) ), isso não resultou no comportamento desejado, pois a substituição do caractere por um caractere vazio deu o mesmo comprimento que a string original. Isso não faz muito sentido para mim, mas eu pude ignorar o problema com o código abaixo:
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
Agora entendo que esse código não resolverá o problema do T-SQL porque não há alternativa à INSTR
função que oferece oOccurence
propriedade.
Apenas para ser aprofundado, adicionarei o código necessário para criar esta função escalar, para que possa ser usada da mesma maneira que fiz nos exemplos acima.
-- 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 o óbvio, quando a REVERSE
função está disponível, você não precisa criar essa função escalar e pode obter o resultado necessário da seguinte maneira:
SELECT
LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo