这可以清理/优化,并且故意冗长,但应该让你开始。值得注意的是,最后一个 IF 内部的逻辑几乎与 WHILE 的逻辑相同,并且获取左/右元素数值的块重复了四次。
declare @input varchar(max)
set @input = 'R1,R15-R19,RN5-RN6'
select @input
declare @elements table
(
Element varchar(10),
[Count] int
)
declare @element varchar(10)
declare @index int
declare @count int
declare @left varchar(10)
declare @right varchar(10)
declare @position int
while (len(@input) > 0 and charindex(',', @input) > 0)
begin
set @element = substring(@input, 0, charindex(',', @input))
if (charindex('-', @element) > 0)
begin
set @index = charindex('-', @element)
set @left = left(@element, @index - 1)
set @right = substring(@element, @index + 1, len(@element) - len(@left))
set @position = 0
while (isnumeric(substring(@left, @position, 1)) = 0)
begin
set @position = @position + 1
end
set @left = substring(@left, @position, len(@left))
set @position = 0
while (isnumeric(substring(@right, @position, 1)) = 0)
begin
set @position = @position + 1
end
set @right = substring(@right, @position, len(@right))
set @count = cast(@right as int) - cast(@left as int) + 1
end
else
begin
set @count = 1
end
insert into @elements select @element, @count
set @input = replace(@input, @element + ',', '')
end
if (len(@input) > 0)
begin
set @element = @input
if (charindex('-', @element) > 0)
begin
set @index = charindex('-', @element)
set @left = left(@element, @index - 1)
set @right = substring(@element, @index + 1, len(@element) - len(@left))
set @position = 0
while (isnumeric(substring(@left, @position, 1)) = 0)
begin
set @position = @position + 1
end
set @left = substring(@left, @position, len(@left))
set @position = 0
while (isnumeric(substring(@right, @position, 1)) = 0)
begin
set @position = @position + 1
end
set @right = substring(@right, @position, len(@right))
set @count = cast(@right as int) - cast(@left as int) + 1
end
else
begin
set @count = 1
end
insert into @elements select @element, @count
end
select * from @elements
select sum([Count]) from @elements
输出以下结果:
R1,R15-R19,RN5-RN6
R1 1
R15-R19 5
RN5-RN6 2
8