2010-10-27 5 views
4

Я хотел знать, есть ли в SQL Server эквивалент функции Oracle INSTR?
Я знаю, что есть CHARINDEX и PATINDEX, но с версией Oracle я также могу указать N-й вид символов, которые я ищу.SQL Server, эквивалентный ORACLE INSTR

Oracle INSTR:

instr(string1, string2 [, start_position [, **nth_appearance** ] ]) 

CHARINDEX почти получает меня там, но я хотел, чтобы это началось в nth_appearance символа в строке.

ответ

4

Вы были на месте, что nth_appearance не существует в SQL Server.

Бесстыдно копирование функции (Equivalent of Oracle's INSTR with 4 parameters in SQL Server), созданный для вашей проблемы (пожалуйста, обратите внимание, что @Occurs не используется таким же образом, как и в Oracle - вы не можете указать «3-й вид», но «происходит в 3 раза»):

CREATE FUNCTION udf_Instr 
    (@str1 varchar(8000), @str2 varchar(1000), @start int, @Occurs int) 
RETURNS int 
AS 
BEGIN 
    DECLARE @Found int, @LastPosition int 
    SET @Found = 0 
    SET @LastPosition = @start - 1 

    WHILE (@Found < @Occurs) 
    BEGIN 
     IF (CHARINDEX(@str1, @str2, @LastPosition + 1) = 0) 
      BREAK 
      ELSE 
      BEGIN 
       SET @LastPosition = CHARINDEX(@str1, @str2, @LastPosition + 1) 
       SET @Found = @Found + 1 
      END 
    END 

    RETURN @LastPosition 
END 
GO 

SELECT dbo.udf_Instr('x','axbxcxdx',1,4) 
GO 


DROP FUNCTION udf_Instr 
GO 
+0

Thansk moontear ..... Я создал функцию, просто надеялся, что вместо этого могу использовать SQL-сервер. Спасибо за пример функции. – scarpacci

0

Изменение @str1 varchar(8000), @str2 varchar(1000) в @str1 varchar(1000), @str2 varchar(8000)

или изменения CHARINDEX(@str1, @str2, @LastPosition + 1) в CHARINDEX(@str2, @str1, @LastPosition + 1)

0

Вы можете использовать следующую UDF (встроенная функция, а не скалярная)

CREATE FUNCTION dbo.INSTR 
(
@str VARCHAR(8000), 
@Substr VARCHAR(1000), 
@start INT , 
@Occurance INT 
) 
RETURNS TABLE 
AS 
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([email protected] +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 

Как использовать:

declare @T table 
(
Name_Level_Class_Section varchar(25) 
) 
insert into @T values 
    ('Jacky_1_B2_23'), 
    ('Johnhy_1_B2_24'), 
    ('Peter_2_A5_3') 

    select t.Name_Level_Class_Section , l.Loc 
    from @t t 
    cross apply dbo.INSTR (t.Name_Level_Class_Section, '_',1,2) l 
Смежные вопросы