Tôi đã xem qua chủ đề này trong khi tìm kiếm một giải pháp cho vấn đề tương tự của tôi có cùng yêu cầu chính xác nhưng đối với một loại cơ sở dữ liệu khác cũng thiếu REVERSE
chức năng.
Trong trường hợp của tôi, đây là cơ sở dữ liệu OpenEdge (Progress) , có cú pháp hơi khác. Điều này làm cho INSTR
chức năng có sẵn cho tôi mà hầu hết các cơ sở dữ liệu gõ của Oracle cung cấp .
Vì vậy, tôi đã đưa ra mã sau đây:
SELECT
INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/', ''))) AS IndexOfLastSlash
FROM foo
Tuy nhiên, đối với tình huống cụ thể của tôi (là cơ sở dữ liệu OpenEdge (Tiến trình) ), điều này không dẫn đến hành vi mong muốn vì thay thế ký tự bằng một char trống có cùng độ dài với chuỗi gốc. Điều này không có ý nghĩa nhiều với tôi nhưng tôi đã có thể bỏ qua vấn đề với mã dưới đây:
SELECT
INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/', 'XX')) - LENGTH(foo.filepath)) AS IndexOfLastSlash
FROM foo
Bây giờ tôi hiểu rằng mã này sẽ không giải quyết được vấn đề cho T-SQL vì không có sự thay thế nào cho INSTR
chức năng cung cấpOccurence
tính.
Để được kỹ lưỡng, tôi sẽ thêm mã cần thiết để tạo hàm vô hướng này để nó có thể được sử dụng giống như tôi đã làm trong các ví dụ trên.
-- 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
Để tránh điều hiển nhiên, khi REVERSE
hàm có sẵn, bạn không cần tạo hàm vô hướng này và bạn chỉ có thể nhận được kết quả cần thiết như thế này:
SELECT
LEN(foo.filepath) - CHARINDEX('/', REVERSE(foo.filepath))+1 AS LastIndexOfSlash
FROM foo