2010-10-27 5 views
4

Je voulais savoir si dans SQL Server, il existe un équivalent à la fonction Oracle INSTR?
Je sais qu'il y a et PATINDEX, mais avec la version Oracle, je peux aussi spécifier la Nième apparence du ou des caractères que je recherche.SQL Server équivalent à ORACLE INSTR

Oracle INSTR:

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

Le CHARINDEX m'a presque y arrive, mais je voulais avoir commencer à la nth_appearance du caractère dans la chaîne.

Répondre

4

Vous étiez sur que nth_appearance n'existe pas dans SQL Server.

copie sans vergogne une fonction (Equivalent of Oracle's INSTR with 4 parameters in SQL Server) créé pour votre problème (s'il vous plaît noter que @Occurs n'est pas utilisé la même manière que dans Oracle - vous ne pouvez pas spécifier « 3ème apparence », mais « se produit 3 fois »):

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 ..... J'ai créé une fonction, était juste en espérant que je pouvais utiliser une fonction de serveur SQL à la place. Merci pour l'exemple de fonction. – scarpacci

0

changement @str1 varchar(8000), @str2 varchar(1000) à @str1 varchar(1000), @str2 varchar(8000)

ou changement CHARINDEX(@str1, @str2, @LastPosition + 1)-CHARINDEX(@str2, @str1, @LastPosition + 1)

0

Vous pouvez utiliser le (UDF suivant fonction en ligne plutôt que scalaire)

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 

Comment utiliser:

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 
Questions connexes