programing

SQL Server에 LastIndexOf가 있습니까?

bestprogram 2023. 4. 17. 22:34

SQL Server에 LastIndexOf가 있습니까?

문자열마지막 인덱스를 가져오는 문자열에서 값을 구문 분석하려고 합니다.현재 저는 문자열을 되돌리는 끔찍한 해킹을 하고 있습니다.

SELECT REVERSE(SUBSTRING(REVERSE(DB_NAME()), 1, 
    CHARINDEX('_', REVERSE(DB_NAME()), 1) - 1))

나에게 이 코드는 거의 읽을 수 없다.SQL Server 2016으로 방금 업그레이드 했는데 더 좋은 방법이 있었으면 좋겠어요.있어?

마지막 이후에 모든 것을 원한다면_, 그 후 다음을 사용합니다.

select right(db_name(), charindex('_', reverse(db_name()) + '_') - 1)

모든 것을 원하신다면left():

select left(db_name(), len(db_name()) - charindex('_', reverse(db_name()) + '_'))

선택한 문자의 LastIndexOf를 반환하는 함수 2개를 썼습니다.

CREATE FUNCTION dbo.LastIndexOf(@source nvarchar(80), @pattern char)
RETURNS int
BEGIN  
       RETURN (LEN(@source)) -  CHARINDEX(@pattern, REVERSE(@source)) 
END;  
GO

및 1은 이 LastIndexOf 이전 문자열을 반환합니다.누군가에게 도움이 될지도 몰라요.

CREATE FUNCTION dbo.StringBeforeLastIndex(@source nvarchar(80), @pattern char)
RETURNS nvarchar(80)
BEGIN  
       DECLARE @lastIndex int
       SET @lastIndex = (LEN(@source)) -  CHARINDEX(@pattern, REVERSE(@source)) 

     RETURN SUBSTRING(@source, 0, @lastindex + 1) 
     -- +1 because index starts at 0, but length at 1, so to get up to 11th index, we need LENGTH 11+1=12
END;  
GO

아니요, SQL Server에 LastIndexOf가 없습니다.

사용 가능한 문자열 함수입니다.

하지만 당신은 언제든지 당신만의 기능을 만들 수 있습니다.

CREATE FUNCTION dbo.LastIndexOf(@source text, @pattern char)  
RETURNS 
AS       
BEGIN  
    DECLARE @ret text;  
    SELECT into @ret
           REVERSE(SUBSTRING(REVERSE(@source), 1, 
           CHARINDEX(@pattern, REVERSE(@source), 1) - 1))
    RETURN @ret;  
END;  
GO 

여기서부터 분할된 스트링 중 하나를 얻으면 이렇게 세트 베이스로 할 수 있습니다.

declare @string varchar(max)
set @string='C:\Program Files\Microsoft SQL Server\MSSQL\DATA\AdventureWorks_Data.mdf'

;with cte
as
(select *,row_number() over (order by (select null)) as rownum
from [dbo].[SplitStrings_Numbers](@string,'\')
)
select top 1 item from cte order by rownum desc

**Output:**  
AdventureWorks_Data.mdf
CREATE FUNCTION dbo.LastIndexOf(@text NTEXT, @delimiter NTEXT)  
RETURNS INT
AS       
BEGIN  
  IF (@text IS NULL) RETURN NULL;
  IF (@delimiter IS NULL) RETURN NULL;
  DECLARE @Text2 AS NVARCHAR(MAX) = @text;
  DECLARE @Delimiter2 AS NVARCHAR(MAX) = @delimiter;
  DECLARE @Index AS INT = CHARINDEX(REVERSE(@Delimiter2), REVERSE(@Text2));
  IF (@Index < 1) RETURN 0;
  DECLARE @ContentLength AS INT = (LEN('|' + @Text2 + '|') - 2);
  DECLARE @DelimiterLength AS INT = (LEN('|' + @Delimiter2 + '|') - 2);
  DECLARE @Result AS INT = (@ContentLength - @Index - @DelimiterLength + 2);
  RETURN @Result;
END
  • " , " (콤마 공백)와 같은 다중 문자 구분 기호를 사용할 수 있습니다.
  • 딜리미터를 찾을 수 없는 경우 0을 반환합니다.
  • NVARCHAR(MAX)가 NTEXT에 암시적으로 캐스팅되지만 그 반대는 아닙니다.
  • 선행 또는 후행 공백이 있는 구분 기호를 올바르게 처리합니다.

시험:

select LEN('tran van abc') + 1 - CHARINDEX(' ', REVERSE('tran van abc'))

그래서 '의 마지막 색인은 9 입니다.

이 스레드는 동일한 요건을 가지고 있었지만 다른 종류의 데이터베이스를 위한 유사한 문제에 대한 해결책을 찾다가 우연히 발견되었습니다.REVERSE기능.

이 경우 구문이 약간 다른 OpenEdge(Progress) 데이터베이스용입니다.이 때문에,INSTR대부분의 Oracle 유형 데이터베이스가 제공하는 기능을 사용할 수 있습니다.

그래서 저는 다음과 같은 코드를 생각해 냈습니다.

SELECT 
  INSTR(foo.filepath, '/',1, LENGTH(foo.filepath) - LENGTH( REPLACE( foo.filepath, '/',  ''))) AS IndexOfLastSlash 
FROM foo

그러나 특정 상황(OpenEdge(Progress) 데이터베이스)에서는 문자를 빈 문자로 대체하면 원래 문자열과 길이가 같기 때문에 원하는 동작이 되지 않았습니다.이것은 별로 납득이 가지 않지만, 이하의 코드로 문제를 회피할 수 있었습니다.

SELECT 
  INSTR(foo.filepath, '/',1, LENGTH( REPLACE( foo.filepath, '/',  'XX')) - LENGTH(foo.filepath))  AS IndexOfLastSlash 
FROM foo

코드로는 T-SQL의 문제를 해결할 수 없다는 것을 알게 되었습니다. 왜냐하면 T-SQL에는 다른 대안이 없기 때문입니다.INSTR를 제공하는 기능Occurence소유물.

이 스칼라 함수를 작성하기 위해 필요한 코드를 추가하여 위의 예시와 동일하게 사용할 수 있도록 하겠습니다.또한 SQL Server의 LastIndexOf 메서드로서 OP가 원하는 대로 실행할 수 있습니다.

  -- Drop the function if it already exists
  IF OBJECT_ID('INSTR', 'FN') IS NOT NULL
    DROP FUNCTION INSTR
  GO

  -- User-defined function to implement Oracle INSTR in SQL Server
  CREATE FUNCTION INSTR (@str VARCHAR(8000), @substr VARCHAR(255), @start INT, @occurrence INT)
  RETURNS INT
  AS
  BEGIN
    DECLARE @found INT = @occurrence,
            @pos INT = @start;

    WHILE 1=1 
    BEGIN
        -- Find the next occurrence
        SET @pos = CHARINDEX(@substr, @str, @pos);

        -- Nothing found
        IF @pos IS NULL OR @pos = 0
            RETURN @pos;

        -- The required occurrence found
        IF @found = 1
            BREAK;

        -- Prepare to find another one occurrence
        SET @found = @found - 1;
        SET @pos = @pos + 1;
    END

    RETURN @pos;
  END
  GO

것을 , 「이것들」이 「이것들」의 에.REVERSE함수를 사용할 수 있습니다.이 스칼라 함수를 작성할 필요가 없습니다.필요한 결과는 다음과 같습니다.

SELECT
  LEN(foo.filepath) - CHARINDEX('\', REVERSE(foo.filepath))+1 AS LastIndexOfSlash 
FROM foo

이거 먹어봐.

drop table #temp
declare @brokername1 nvarchar(max)='indiabullssecurities,canmoney,indianivesh,acumencapitalmarket,sharekhan,edelweisscapital';
Create Table #temp
(
ID int identity(1,1) not null,
value varchar(100) not null
)

INSERT INTO #temp(value) SELECT value from STRING_SPLIT(@brokername1,',')
declare @id int;
set @id=(select max(id) from #temp)
--print @id
declare @results varchar(500)
select @results = coalesce(@results + ',', '') +  convert(varchar(12),value)
from #temp where id<@id
order by id
print @results

언급URL : https://stackoverflow.com/questions/39002025/is-there-a-lastindexof-in-sql-server