2017-03-02 46 views
1

我一直在尋找一種方式來動態解析字符串:SQL-只保留方括號,裏面的數據的

輸入:A[1]/B2[2]/C_D[1]

輸出:[1][2][1]

+1

現在你應該知道,你應該告訴我們你的努力...... –

+0

我已經嘗試做這件事通過PATINDEX,但是這不是動態的..因爲在方括號內數字可以 –

回答

2

只需用while循環。

declare @str varchar(max), @newStr varchar(max), @orgStr varchar(max) 
set @orgStr = 'A[1]/B2[2]/C_D[1]' 
set @newStr = '' 
set @Str = @orgStr 
while (1=1) 
begin 
    if (CHARINDEX('[',@str) <> 0) 
     begin 
      set @newStr = @newStr + SUBSTRING(@str,CHARINDEX('[',@str), CHARINDEX(']',@str) - CHARINDEX('[',@str)+1) 
      set @str = STUFF(@str, CHARINDEX('[',@str), CHARINDEX(']',@str) - CHARINDEX('[',@str)+1, '') 
     end 
    else 
     break 
end 
select @orgStr as input, @newStr as result 
+0

正是我在找的東西!!! –

2

你可以嘗試STRING_SPLIT,如果您的兼容性級別爲130或更高。 (不是Azure的默認設置,根據文檔,您可能需要更改數據庫範圍的設置。)

如果將字符串拆分爲'[',那麼您將有兩組值:包含']'而那些不是。如果您的字符串包含平衡的左右括號,則第一個單詞不應該有']',因爲它包含第一個開頭'['之前的所有內容。每隔一個字就應該包含一個關閉']'。

您可以刪除第一個單詞,然後在']上再應用STRING_SPLIT。此時,let's-call-even-even行將成爲索引,並且這些調用它們的奇數行將在']'之後和下一個'['之前成爲文本。

像這樣:

s = 'firstword[1][2] another word [foobar] biscuit' 

SELECT VALUE FROM STRING_SPLIT(s, '[') 

應該讓你:

1: 'firstword' #<-- No brackets here 
2: '1]' 
3: '2] another word ' 
4: 'foobar] biscuit' 

可以刪除第一行,當然。再次應用SPLIT_STRING將讓你:

'1', '' 
'2', ' another word' 
'foobar', ' biscuit' 

保持左側立柱,丟棄右列,和鮑勃是你的叔叔!

+0

感謝幫助+1幫助 –

2

使用SUBSTRING和CHARINDEX內置函數在CTE:

DECLARE @String VARCHAR(200) = 'A[1]/B2[2]/C_D[1]' 
;WITH CTE_Split(SplitStr , String) AS 
(
    SELECT SUBSTRING(@String  
    ,CHARINDEX('[',@String),CHARINDEX('[',@String)+1),SUBSTRING(@String 
    ,CHARINDEX('/',@String)+1,LEN(@String)) 
    UNION ALL 
    SELECT CASE WHEN CHARINDEX('[',String) = 0 THEN '' ELSE SUBSTRING(String 
    ,CHARINDEX('[',String),CHARINDEX('[',String)) END, 
    CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE SUBSTRING(String 
    ,CHARINDEX('/',String)+1,LEN(String)) END 
    FROM CTE_Split 
    WHERE String <> '' 
) 

    SELECT SplitStr FROM CTE_Split 

    [OR] 

    This query for all scenarios : 

    DECLARE @String VARCHAR(200) = 'A[1]/B2[2]/C_D[1]/C_D[288]/' 

    ;WITH CTE_Split(SplitStr , String) AS 
    (
     SELECT SUBSTRING(@String,0,CHARINDEX('/',@String)),SUBSTRING(@String 
     ,CHARINDEX('/',@String)+1,LEN(@String)) 
     UNION ALL 
     SELECT CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE 
     SUBSTRING(String ,0,CHARINDEX('/',String)) END, 
     CASE WHEN CHARINDEX('/',String) = 0 THEN '' ELSE SUBSTRING(String 
     ,CHARINDEX('/',String)+1,LEN(String)) END 
     FROM CTE_Split 
     WHERE String <> '' 
) 

    SELECT SUBSTRING(SplitStr,CHARINDEX('[',SplitStr),CHARINDEX(']',SplitStr)) 
    FROM CTE_Split 
+1

以DECLARE @String VARCHAR(200)='A [1]/B2 [223]/C_D [1]'失敗。我建議使用']'作爲結尾字符串delimeter而不是'/' –

+0

用DECLARE @String VARCHAR(200)='A [1]/B2 [223]/C_D [1]/E_F'''' –

+0

是的,這隻適用於特定場景.. –

1

--===== Create and populate the Tally table on the fly 
 
SELECT TOP 11000 --equates to more than 30 years of dates 
 
     IDENTITY(INT,1,1) AS N 
 
    INTO dbo.Tally 
 
    FROM Master.dbo.SysColumns sc1, 
 
     Master.dbo.SysColumns sc2 
 

 
--===== Add a Primary Key to maximize performance 
 
    ALTER TABLE dbo.Tally 
 
    ADD CONSTRAINT PK_Tally_N 
 
     PRIMARY KEY CLUSTERED (N) WITH FILLFACTOR = 100 
 

 
--===== Allow the general public to use it 
 
    GRANT SELECT ON dbo.Tally TO PUBLIC 
 

 

 
    --===== Simulate a passed parameter 
 
DECLARE @Parameter VARCHAR(8000) 
 
    SET @Parameter = 'A[1]/B2[2]/C_D[1]' 
 

 
--===== Suppress the auto-display of rowcounts to keep them from being 
 
    -- mistaken as part of the result set. 
 
    SET NOCOUNT ON 
 

 
--===== Get the items in the brackets and number them 
 
SELECT '[' + SUBSTRING(@Parameter,N+1,CHARINDEX(']',@Parameter,N+1)-N-1) + ']' 
 
    FROM dbo.Tally 
 
    WHERE N < LEN(@Parameter) 
 
    AND SUBSTRING(@Parameter,N,1) = '['

請試試你的邏輯就像這個

+0

謝謝!適合我! –

+0

感謝Piyush ............................................... ................ –

1

可以通過一個while循環結合子字符串和charindex來完成。

查詢

declare @str as varchar(max) = 'A[1]/B2[2]/C_D[1]'; 
declare @len as int = len(@str); 
declare @i as int = 0; 
declare @str2 as varchar(max) = @str; 
declare @res as varchar(max) = ''; 

while(@len >= @i) 
begin 
    if (charindex('[',@str2) <> 0) 
    begin 
     set @res += substring(@str2, 
           charindex('[', @str2, 1), 
           charindex(']', @str2, 1) - charindex('[', @str2, 1) + 1) 
     set @i += charindex(']', @str2, 1); 
     set @str2 = right(@str2, @len - @i) 
    end 
    else 
     break;  
end 
select @res;