我正在处理一个名为FullName
的列,它存储了一个很长的值。
格式类似于
'Microsoft.SQL.Server.20XX.DBFile:ABC.edf.com;XXXX_XXX_XXX;master;1;1'
'SQLVersion.DBFile:Hostname;InstanceName;Dummy;Dummy;Dummy'
我想要的是将FullName
分成SQLVersion
,Hostname
和InstanceName
。
我搜索了一些关于拆分值的线程,这些值用点或冒号分隔,这与我的情况略有不同。
答案 0 :(得分:1)
您可以在cross apply
中使用以下技巧。我认为代码是自解释的,不需要详细说明:
create table t(v varchar(200))
insert into t values
('Microsoft.SQL.Server.20XX.DBFile:ABC.edf.com;XXXX_XXX_XXX;master;1;1'),
('SQLVersion.DBFile:Hostname;InstanceName;Dummy;Dummy;Dummy')
select substring(v, 1, c1.i1 - 1) as SqlVersion,
substring(v, c1.i1 + 1, c2.i2 - c1.i1 - 1) as HostName,
substring(v, c2.i2 + 1, c3.i3 - c2.i2 - 1) as InstanceName
from t
cross apply(select charindex(':', t.v) as i1 ) c1
cross apply(select charindex(';', t.v, c1.i1 + 1) as i2) c2
cross apply(select charindex(';', t.v, c2.i2 + 1) as i3) c3
如果不清楚。在第一次交叉申请中,我选择了符号:
的索引。在第二次交叉申请中,我选择符号;
的索引,该索引位于第一次交叉申请的索引之后。第三,应用第二个交叉索引之后的符号;
的索引。在主要选择中,我只是使用这些indeces来获取所需的字符串部分。
答案 1 :(得分:0)
我同意上面的评论,如果可能的话,首选单独的列。但是,我相信这个解析逻辑正在做你想要的:
declare
@test nvarchar(200)
, @versionStart int
, @versionLength int
, @hostStart int
, @hostLength int
, @instanceStart int
, @instanceLength int
SET @test = 'Microsoft.SQL.Server.20XX.DBFile:ABC.edf.com;XXXX_XXX_XXX;master;1;1'
SET @versionStart = PATINDEX('%Microsoft.SQL.Server.%', @test) + 21
SET @versionLength = CHARINDEX('.', @test, @versionStart) - @versionStart
SET @hostStart = PATINDEX('%.DBFile:%', @test) + 8
SET @hostLength = CHARINDEX(';', @test, @hostStart) - @hostStart
SET @instanceStart = CHARINDEX(';', @test, @hostStart + @hostLength) + 1
SET @instanceLength = CHARINDEX(';', @test, @instanceStart) - @instanceStart
select
SUBSTRING(@test, @versionStart, 4) AS Version
, SUBSTRING(@test, @hostStart, @hostLength) AS HostName
, SUBSTRING(@test, @instanceStart, @instanceLength) AS InstanceName