2016-08-17 155 views
14

我想解析出一個字符串的值,其中涉及獲取stringlastindex。目前,我正在做一個可怕的破解,涉及扭轉一個字符串:SQL Server中是否存在LastIndexOf?

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

對我來說這段代碼幾乎是不可讀的。我剛升級到SQL Server 2016,希望有更好的方法。 是否有?

+2

你能展示你的字符串的一些例子嗎? –

+0

對我來說,這不僅是不可讀的,也不能猜測你想要的樣本數據:) – techspider

+2

愛得堆棧溢出人們的第一反應是要求更多的信息,即使這個問題不需要更多的信息來解決它:) –

回答

36

如果你想要的一切,最後_後,再使用:

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

如果你之前想要的一切,然後使用left()

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

@dnoeth。 。 。是的,謝謝。 –

+0

我不得不將第一個表達式改爲:'right(db_name(),charindex('_',reverse(db_name())+'_') - 1)'使它成功!否則太棒了! – Egahn

1

一旦你有split strings from here之一,你可以以這樣的集合方式來做它..

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 
2

不,SQL服務器d oesnt有LastIndexOf。

這是可用的字符串functions

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 
1

我碰到這個線程就可以隨時可以創建自己的功能,而尋找一個解決方案,我這有完全相同類似的問題相同的要求,但是對於缺少REVERSE功能的不同種類的數據庫。

在我的情況下,這是一個OpenEdge(Progress)數據庫,它有一個稍微不同的語法。這使得INSTR函數對我可用,即most Oracle typed databases offer

所以我用下面的代碼上來:

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

但是,對於我的具體情況(爲OpenEdge(進展)數據庫),這並不會導致到所需的行爲,因爲與替換字符一個空的字符與原始字符串的長度相同。這並沒有太大的意義給我,但我能夠繞過與下面的代碼的問題:

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

現在我明白了,這個代碼將不會解決問題的T-SQL因爲除了提供Occurence屬性的INSTR函數,沒有其他選擇。

爲了徹底,我將添加創建此標量函數所需的代碼,以便可以像我在上面的示例中那樣使用它。並且將完成OP所需的任務,作爲S​​QL Server的LastIndexOf方法。

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

寫了2個功能,1返回LastIndexOf爲選定的字符。

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

和1在此LastIndexOf之前返回一個字符串。也許這對某個人有用。

CREATE FUNCTION dbo.StringBeforeLastIndex(@source nvarchar(20), @pattern char) 
RETURNS nvarchar(20) 
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 
1
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。
  • 出於舒適性考慮採用NTEXT,因爲NVARCHAR(MAX)隱式轉換爲NTEXT,反之則不然。
  • 正確處理帶有前導或尾隨空格的分隔符!
相關問題