2009-12-05 6 views
10

У меня есть строка 'some.file.name', я хочу захватить 'some.file'.SQL Server 2005: charindex, начиная с конца

Для этого мне нужно найти последнее вхождение '.' в строке.

Мое решение:

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) 

Ну, не слишком сложен, я просто intented с помощью «some.file» в где-п?.

У кого-нибудь есть хорошая идея?

+0

@Shuo: обновите свой ответ для вашего сценария - должно работать нормально. –

+0

Спасибо, Марк! Я пересмотрел свой вопрос. Вы очень поможете! Если бы кто-то не мог дать мне лучшую идею, я бы пометил ваш ответ =) – Shuo

ответ

16

Что вам нужно для этого? Вам нужно захватить символы после последнего появления данного разделителя?

Если это так: обратный строку и поиск с помощью обычного CHARINDEX:

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)) 

вы получите обратно «some.file» - персонажей до последнего «» в исходном имени файла.

В SQL Server нет ни одного «LASTCHARINDEX» или чего-либо подобного. То, что вы могли бы подумать о том, чтобы делать в SQL Server 2005 и выше, является большой библиотекой расширений .NET и развертывает ее как сборку в SQL Server. T-SQL не очень силен с помощью строковых манипуляций, тогда как .NET действительно есть.

+0

Hey Marc, Спасибо за ваш ответ. У меня есть строка типа 'some.file.name' Я хочу захватить 'some.file'.if, используя LEFT, мне нужно знать индекс последнего разделителя. У вас есть хорошая идея захватить' некоторые. файл'? – Shuo

+0

@Shuo: Почему бы вам не пойти и не приложить больше усилий. Тогда другие могут быть более склонны помочь вам. –

+0

@Shuo: обновите свой ответ для вашего сценария - должно работать нормально. –

5

Это также будет работать:

DECLARE 
    @test  VARCHAR(100) 

SET @test = 'some.file.name' 

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

Том, мы видим глаз до глаз! – Shuo

+0

Хех! Просмотрев код Марка и прочитав все комментарии, затем, отвлекаясь на что-то еще, я полностью забыл, что было вашим решением :) –

1

Возьмите один ')'

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

Вот сокращенный вариант

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

очень простой способ:

выберите право (@ str, charindex ('.', Reverse (@str)) - 1)