我一直在寻找一种动态解析字符串的方法:
输入: A[1]/B2[2]/C_D[1]
输出: [1][2][1]
答案 0 :(得分:2)
如果兼容级别为130或更高,则可以尝试STRING_SPLIT
。 (根据文档,不是Azure的默认设置。您可能必须在数据库范围内更改设置。)
如果您将字符串拆分为' [',那么您将拥有两组值:包含']'那些不是。如果你的字符串包含平衡的左右括号,则第一个单词应该没有']',因为它包含第一个开头之前的所有内容' ['。其他所有单词都应包含结尾']'。
您可以删除第一个字,然后在']'上再次应用STRING_SPLIT
。此时,let-call-them-even行将成为索引,而call-they-odd行将是']'之后的文本。在下一个' ['。
像这样:
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'
保留左栏,丢弃右栏,鲍勃是你的叔叔!
答案 1 :(得分:2)
在CTE中使用SUBSTRING和CHARINDEX内置函数:
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
答案 2 :(得分: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
答案 3 :(得分: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) = '['
&#13;
请尝试像这样的逻辑
答案 4 :(得分:1)
可以通过子循环和charindex的组合使用while循环。
<强>查询强>
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;