2009-12-05 10 views
10

Tengo una cadena 'some.file.name', quiero obtener 'some.file'.SQL Server 2005: charindex comenzando desde el final

Para hacer eso, necesito encontrar la última aparición de '.' en una cuerda.

Mi solución es:

declare @someStr varchar(20) 

declare @reversedStr varchar(20) 

declare @index int 

set @someStr = '001.002.003' 

set @reversedStr = reverse(@someStr) 

set @index = len(@someStr) - charindex('.',@reversedStr) 

select left(@someStr,@index) 

Bueno, no es demasiado complicado Estaba intented a utilizar 'some.file' en una cláusula where?.

¿Alguien tiene una buena idea?

+0

@Shuo: actualizar mi respuesta para su escenario - debería funcionar bien. –

+0

Gracias, Marc! He revisado mi pregunta. ¡Eres muy útil! Si alguien no pudiera darme una mejor idea, marcaría tu respuesta =) – Shuo

Respuesta

16

¿Qué tienes que hacer con eso? ¿Necesita agarrar los caracteres después de la última ocurrencia de un delimitador dado?

Si es así: revertir la cuerda y realizar búsquedas con los CHARINDEX normales:

declare @test varchar(100) 
set @test = 'some.file.name' 

declare @reversed varchar(100) 
set @reversed = REVERSE(@test) 

select 
    REVERSE(SUBSTRING(@reversed, CHARINDEX('.', @reversed)+1, 100)) 

que pondremos en contacto "some.file" - los caracteres que aparecen hasta el último "" en el nombre del archivo original.

No hay "LASTCHARINDEX" o algo así en SQL Server directamente. Lo que podría considerar hacer en SQL Server 2005 y posteriores es una gran biblioteca de extensiones .NET y desplegarlo como un ensamblado en SQL Server: T-SQL no es muy fuerte con la manipulación de cadenas, mientras que .NET sí lo es.

+0

Hey Marc, Gracias por tu respuesta. Tengo una cadena como 'some.file.name' Quiero obtener 'some.file'.if usando IZQUIERDA, necesito saber el índice del último delimitador. ¿Tiene alguna buena idea para obtener' algunos '? archivo'? – Shuo

+0

@Shuo: ¿Por qué no tener un ir usted mismo y publicar su mejor esfuerzo. Entonces, otros pueden estar más dispuestos a ayudarlo. –

+0

@Shuo: actualice mi respuesta para su escenario, debería funcionar bien. –

5

Esto también funciona:

DECLARE 
    @test  VARCHAR(100) 

SET @test = 'some.file.name' 

SELECT 
    LEFT(@test, LEN(@test) - CHARINDEX('.', REVERSE(@test))) 
+0

Tom, estamos viendo cara a cara! – Shuo

+0

¡Heh! Después de revisar el código de Marc y leer todos los comentarios, luego de distraerme con algo más, olvidé por completo cuál había sido tu solución :) –

1

Tome un ')'

declare @test varchar(100) 
set @test = 'some.file.name' 
select left(@test,charindex('.',@test)+charindex('.',@test)-1) 
0

Aquí es una versión más corta

DECLARE @someStr varchar(20) 
set @someStr = '001.002.003' 

SELECT REVERSE(Substring(REVERSE(@someStr),CHARINDEX('.', REVERSE(@someStr))+1,20)) 
1
CREATE FUNCTION [dbo].[Instr] (
    ------------------------------------------------------------------------------------------------- 
    -- Name:  [dbo].[Instr] 
    -- Purpose: Find The Nth Value Within A String 
    ------------------------------------------------------------------------------------------------- 
    -- Revisions: 
    -- 25-FEB-2011 - HESSR - Initial Revision 
    ------------------------------------------------------------------------------------------------- 
    -- Parameters: 
    -- 1) @in_FindString - NVARCHAR(MAX) - INPUT - Input Find String 
    -- 2) @in_String - NVARCHAR(MAX) - INPUT - Input String 
    -- 3) @in_StartPos - SMALLINT - INPUT - Position In The String To Start Looking From 
    --   (If Start Position Is Negative, Search Begins At The End Of The String) 
    --   (Negative 1 Starts At End Position 1, Negative 3 Starts At End Position Minus 2) 
    -- 4) @in_Nth - SMALLINT - INPUT - Nth Occurrence To Find The Location For 
    ------------------------------------------------------------------------------------------------- 
    -- Returns: SMALLINT - Position Of String Segment (Not Found = 0) 
    ------------------------------------------------------------------------------------------------- 
    @in_FindString    NVARCHAR(MAX), 
    @in_String     NVARCHAR(MAX), 
    @in_StartPos    SMALLINT   = NULL, 
    @in_Nth     SMALLINT   = NULL 
) 
    RETURNS     SMALLINT 
AS 
BEGIN 

    DECLARE @loc_FindString NVARCHAR(MAX); 
    DECLARE @loc_String NVARCHAR(MAX); 
    DECLARE @loc_Position SMALLINT; 
    DECLARE @loc_StartPos SMALLINT; 
    DECLARE @loc_Nth SMALLINT; 
    DECLARE @loc_Idx SMALLINT; 
    DECLARE @loc_FindLength SMALLINT; 
    DECLARE @loc_Length SMALLINT; 

    SET @loc_FindString = @in_FindString; 
    SET @loc_String = @in_String; 

    SET @loc_Nth = ISNULL(ABS(@in_Nth), 1); 
    SET @loc_FindLength = LEN(@loc_FindString+N'.') - 1; 
    SET @loc_Length = LEN(@loc_String+N'.') - 1; 

    SET @loc_StartPos = ISNULL(@in_StartPos, 1); 
    SET @loc_Idx = 0; 

    IF (@loc_StartPos = ABS(@loc_StartPos)) 
    BEGIN 
     WHILE (@loc_Idx < @loc_Nth) 
     BEGIN 
      SET @loc_Position = CHARINDEX(@loc_FindString,@loc_String,@loc_StartPos); 
      IF (@loc_Position > 0) 
      SET @loc_StartPos = @loc_Position + @loc_FindLength 
      ELSE 
      SET @loc_Idx = @loc_Nth; 
      SET @loc_Idx = @loc_Idx + 1; 
     END; 
    END 
    ELSE 
    BEGIN 
     SET @loc_StartPos = ABS(@loc_StartPos); 
     SET @loc_FindString = REVERSE(@in_FindString); 
     SET @loc_String = REVERSE(@in_String); 
     WHILE (@loc_Idx < @loc_Nth) 
     BEGIN 
      SET @loc_Position = CHARINDEX(@loc_FindString,@loc_String,@loc_StartPos); 
      IF (@loc_Position > 0) 
      SET @loc_StartPos = @loc_Position + @loc_FindLength 
      ELSE 
      SET @loc_Idx = @loc_Nth; 
      SET @loc_Idx = @loc_Idx + 1; 
     END; 
     IF (@loc_Position > 0) 
     SET @loc_Position = @loc_Length - @loc_Position + (1 - @loc_FindLength) + 1; 
    END; 

    RETURN (@loc_Position); 

END; 
GO 
4

Una forma muy simple es:

de selección derecha ('' @ str, charindex (, inversa (@str)) - 1)

Cuestiones relacionadas