T-SQL to compress (shorten) IPv6 address
select dbo.udf_IPAddrCompress('2a03:b600:0104:0000:0000:0200:0000:0000');
create function [dbo].[udf_IPAddrCompress]
(
@ip varchar(50)
)
returns varchar(50)
begin
declare @s varchar(50) = @ip;
-- Find and replace the 1st longest all 0's with :: (But only if at least 2 sections of all 0's)
--
declare @x int, @i tinyint = 0, @z varchar(50) = '0000', @start int;
while @i < 7
begin
set @x = charindex(@z + ':0000', @s);
if @x > 0
select @z = @z + ':0000', @start = @x;
else break;
set @i += 1;
end;
if @start > 0
begin
set @s = stuff(@s, @start, len(@z), '');
if left(@s, 1) = ':' set @s = ':' + @s;
if right(@s, 1) = ':' set @s = @s + ':';
if @s = '' set @s = '::';
end
-- Remove leading 0's
--
set @s = ':' + @s;
set @s = replace(replace(replace(@s, ':0', ':'), ':0', ':'), ':0', ':');
set @s = right(@s, len(@s) - 1);
return @s;
end
GO
And here is the set-based alternative to find the longest all 0's that I tried.
declare @p table(TK tinyint identity(1, 1), p varchar(50));
insert into @p(p) values
('0000:0000'), ('0000:0000:0000'), ('0000:0000:0000:0000'), ('0000:0000:0000:0000:0000'), ('0000:0000:0000:0000:0000:0000'), ('0000:0000:0000:0000:0000:0000:0000'),
('0000:0000:0000:0000:0000:0000:0000:0000');
declare @z varchar(50);
select top (1) @z = p from @p where charindex(p, @s) > 0 order by TK desc;