-
Notifications
You must be signed in to change notification settings - Fork 681
/
udf_INSTR.sql
47 lines (45 loc) · 1.49 KB
/
udf_INSTR.sql
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
IF OBJECT_ID('dbo.udf_INSTR', 'IF') IS NULL
EXECUTE ('CREATE FUNCTION dbo.udf_INSTR() RETURNS TABLE AS RETURN SELECT 1 AS A;');
GO
ALTER FUNCTION dbo.udf_INSTR(
@str NVARCHAR(4000),
@substr NVARCHAR(4000),
@start INT,
@Occurance INT
)
RETURNS TABLE
AS
/*
Note
Author: Hannan Kravitz
Original link: http://www.sqlservercentral.com/scripts/SUBSTRING/148570/
Modified Date: 2016-11-17
Example:
SELECT Loc FROM dbo.udf_INSTR ('Hello World', 'l', 1, 1) -- return 3
SELECT Loc FROM dbo.udf_INSTR ('Hello World', 'l', 1, 3) -- return 10
SELECT Loc FROM dbo.udf_INSTR ('Hello World', 'l', 1, 4) -- return NULL
SELECT Loc FROM dbo.udf_INSTR ('Ёжик - это моё имя','ё', 1, 1) -- return 14
*/
RETURN
WITH Tally(N) AS
(
SELECT TOP (LEN(@str)) ROW_NUMBER() OVER (ORDER BY (SELECT NULL))
FROM (VALUES (0),(0),(0),(0),(0),(0),(0),(0)) a(N)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) b(N)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) c(N)
CROSS JOIN (VALUES(0),(0),(0),(0),(0),(0),(0),(0),(0),(0)) d(N)
)
, Find_N_STR AS
(
SELECT
CASE WHEN DENSE_RANK() OVER(PARTITION BY @substr ORDER BY (CHARINDEX(@substr, @str, N))) = @Occurance
THEN MAX(N - @start + 1) OVER (PARTITION BY CHARINDEX(@substr, @str, N))
ELSE 0
END [Loc]
FROM Tally
WHERE CHARINDEX(@substr, @str, N) > 0
)
SELECT Loc= MAX(Loc)
FROM Find_N_STR
WHERE Loc > 0;
GO