まったく同じ要件があり、REVERSE
機能も欠けている別の種類のデータベースに対するものである私の類似の問題の解決策を探しているときに、このスレッドに出くわしました。
私の場合、これはOpenEdge(Progress)データベース用で、構文が少し異なります。これにより、ほとんどのOracle型データベースが提供するINSTR
機能を利用できるようになりました。
だから私は次のコードを思いついた:
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
ただし、私の特定の状況(OpenEdge(Progress)データベースであるため)では、文字を空の文字に置き換えると元の文字列と同じ長さになるため、これは望ましい動作になりませんでした。これは私にはあまり意味がありませんが、以下のコードで問題を回避することができました:
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
プロパティを提供する関数に代わるものがないため、このコードはT-SQLの問題を解決しないことを理解しました。INSTR
Occurence
念のため、このスカラー関数を作成するために必要なコードを追加して、上記の例と同じように使用できるようにします。
-- 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
明らかなことを避けるために、REVERSE
関数が使用可能な場合は、このスカラー関数を作成する必要はなく、次のように必要な結果を取得できます。
SELECT
LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo