SQL Server 2005: charindex, начиная с конца - PullRequest
12 голосов
/ 05 декабря 2009

У меня есть строка 'some.file.name', я хочу получить 'some.file'.

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

Мое решение:

 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)

Ну, разве это не слишком сложно? Я просто намеревался использовать 'some.file' в предложении where.

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

Ответы [ 6 ]

20 голосов
/ 05 декабря 2009

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

Если так: переверните строку и выполните поиск с использованием обычного 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» - символы до последнего «.» в оригинальном имени файла.

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

7 голосов
/ 06 декабря 2009

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

DECLARE
     @test     VARCHAR(100)

SET @test = 'some.file.name'

SELECT
     LEFT(@test, LEN(@test) - CHARINDEX('.', REVERSE(@test)))
3 голосов
/ 23 апреля 2015

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

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

1 голос
/ 18 апреля 2013
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
1 голос
/ 21 апреля 2010

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

declare @test varchar(100)
set @test = 'some.file.name'
select left(@test,charindex('.',@test)+charindex('.',@test)-1)
0 голосов
/ 17 мая 2012

Вот более короткая версия

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

SELECT REVERSE(Substring(REVERSE(@someStr),CHARINDEX('.', REVERSE(@someStr))+1,20))
...