ฉันเจอหัวข้อนี้ในขณะที่ค้นหาวิธีแก้ปัญหาที่คล้ายกันของฉันซึ่งมีข้อกำหนดเหมือนกัน แต่เป็นฐานข้อมูลประเภทอื่นที่ยังไม่มี REVERSE
ฟังก์ชัน
ในกรณีของฉันนี่เป็นฐานข้อมูลOpenEdge (Progress)ซึ่งมีไวยากรณ์ที่แตกต่างกันเล็กน้อย สิ่งนี้ทำให้INSTR
ฉันสามารถใช้งานฟังก์ชันที่ฐานข้อมูลประเภท Oracle ส่วนใหญ่เสนอส่วนใหญ่ของออราเคิลพิมพ์ฐานข้อมูลนำเสนอ
ดังนั้นฉันจึงคิดรหัสต่อไปนี้:
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