SQL Server 合并IP

所给字符串是:用逗号连接起来的无规律的IP(不一定是一个网段),例如:
114.113.112.1,114.113.112.3,114.113.112.10,114.113.112.11,114.113.112.12,114.113.112.13,114.113.112.180
要通过一个函数返回这样的字符串:
114.113.112.1,114.113.112.3,114.113.112.10-13,114.113.112.180
即,连续的IP用“-”把首和尾连接,其它的IP仍以逗号连接,所有IP的趋势是从小大大排列。

  

代码
--函数一:
--
SQL Server Split函数
--
Author:zc_0101 
--
说明:
--
支持分割符多字节
--
使用方法
--
Select * FROM DBO.F_SQLSERVER_SPLIT('1203401230105045','0')    
--
select * from DBO.F_SQLSERVER_SPLIT('abc1234a12348991234','1234')    
 

CREATE FUNCTION F_SQLSERVER_SPLIT(@Long_str varchar(8000),@split_str varchar(100))    
RETURNS  @tmp TABLE(        
    ID          
inT     IDENTITY PRIMARY KEY,      
    short_str   
varchar(8000)    
)    
AS   
BEGIN   
    
DECLARE @long_str_Tmp varchar(8000),@short_str varchar(8000),@split_str_length int   
    
SET @split_str_length = LEN(@split_str)    
    
IF CHARINDEX(@split_str,@Long_str)=1 
         
SET @long_str_Tmp=SUBSTRING(@Long_str,@split_str_length+1,LEN(@Long_str)-@split_str_length)
    
ELSE
         
SET @long_str_Tmp=@Long_str
    
IF CHARINDEX(REVERSE(@split_str),REVERSE(@long_str_Tmp))>1    
        
SET @long_str_Tmp=@long_str_Tmp+@split_str    
    
ELSE   
        
SET @long_str_Tmp=@long_str_Tmp    
    
IF CHARINDEX(@split_str,@long_str_Tmp)=0
        
Insert INTO @tmp select @long_str_Tmp 
    
ELSE
        
BEGIN
            
WHILE CHARINDEX(@split_str,@long_str_Tmp)>0    
                
BEGIN   
                    
SET @short_str=SUBSTRING(@long_str_Tmp,1,CHARINDEX(@split_str,@long_str_Tmp)-1)    
                    
DECLARE @long_str_Tmp_LEN INT,@split_str_Position_END int   
                    
SET @long_str_Tmp_LEN = LEN(@long_str_Tmp)    
                    
SET @split_str_Position_END = LEN(@short_str)+@split_str_length    
                    
SET @long_str_Tmp=REVERSE(SUBSTRING(REVERSE(@long_str_Tmp),1,@long_str_Tmp_LEN-@split_str_Position_END))
                    
IF @short_str<>'' Insert INTO @tmp select @short_str    
                
END           
        
END
    
RETURN     
END 


--函数二
IF OBJECT_ID(N'F_IP_Merge','FN'IS NOT NULL DROP FUNCTION F_IP_Merge
GO
CREATE FUNCTION [dbo].[F_IP_Merge](@IP_str VARCHAR(MAX))
    
RETURNS VARCHAR(MAX)
AS
BEGIN
    
DECLARE @TEMP TABLE(ID INT IDENTITY PRIMARY KEY,IP VARCHAR(50),NUM BIGINT)
    
INSERT INTO @TEMP
    
SELECT SHORT_STR,(CAST(PARSENAME(SHORT_STR,4)+PARSENAME(SHORT_STR,3)+PARSENAME(SHORT_STR,2)+RIGHT(REPLICATE('0',2)+PARSENAME(SHORT_STR,1),3AS BIGINT)) cnt
    
FROM DBO.F_SQLSERVER_SPLIT(@IP_str,','
    
ORDER BY CAST(PARSENAME(SHORT_STR,4AS INT),CAST(PARSENAME(SHORT_STR,3AS INT),CAST(PARSENAME(SHORT_STR,2AS INT),CAST(PARSENAME(SHORT_STR,1AS INT)

    
DECLARE @S VARCHAR(MAX)
    
SELECT @S=ISNULL(@S,'')+IP+MERGE_STR FROM (
    
SELECT *,
    
CASE (SELECT NUM FROM @TEMP B WHERE B.ID=A.ID+1)-NUM 
    
WHEN 1 THEN '-' ELSE ',' END AS MERGE_STR
    
FROM @TEMP A) T 

    
DECLARE @TEMP2 TABLE(ID INT PRIMARY KEY,SHORT_STR VARCHAR(MAX))
    
INSERT INTO @TEMP2 SELECT * from DBO.F_SQLSERVER_SPLIT(@S,',')

    
DECLARE @MIN_ID INT,@MAX_ID INT,@TEM_STR VARCHAR(MAX)
    
SELECT @MIN_ID=MIN(ID),@MAX_ID=MAX(ID) FROM @TEMP2
    
WHILE @MIN_ID<=@MAX_ID
        
BEGIN
            
SELECT @TEM_STR=SHORT_STR FROM @TEMP2 WHERE ID=@MIN_ID
            
IF CHARINDEX('-',@TEM_STR)>0 
                
UPDATE @TEMP2 SET SHORT_STR=(
                    
SELECT  
                        
LTRIM(MAX(CAST(PARSENAME(SHORT_STR,4AS INT)))+'.'+
                        
LTRIM(MAX(CAST(PARSENAME(SHORT_STR,3AS INT)))+'.'+
                        
LTRIM(MAX(CAST(PARSENAME(SHORT_STR,2AS INT)))+'.'+
                        
LTRIM(MIN(CAST(REPLICATE('0',2)+PARSENAME(SHORT_STR,1)AS INT)))+'~'+
                        
LTRIM(MAX(CAST(REPLICATE('0',2)+PARSENAME(SHORT_STR,1)AS INT))) 
                    
FROM DBO.F_SQLSERVER_SPLIT(@TEM_STR,'-')
WHERE ID=@MIN_ID
            
SET @MIN_ID=@MIN_ID+1
        
END
    
    
DECLARE @RESULT VARCHAR(MAX)
    
SELECT @RESULT=ISNULL(@RESULT+'<span style="color:red;">,</span><br />','')+SHORT_STR FROM @TEMP2
    
RETURN @RESULT
END

--执行
SELECT DBO.F_IP_Merge('114.113.112.1,.113.112.3,.113.112.10,.113.112.11,.113.112.12,.113.112.13,.113.112.180')
/*
114.113.112.1,114.113.112.3,114.113.112.10-114.113.112.13,114.113.112.180
*/
SELECT DBO.F_IP_Merge('1.1.254.253,1.1.255.254,1.1.255.255,1.2.0.0,1.2.0.1,1.2.0.6,114.113.112.1,114.113.112.3,114.113.112.10,114.113.112.11,114.113.112.12,114.113.112.13,114.113.112.180')
/*
1.1.254.253,1.1.255.254-1.1.255.255,1.2.0.0-1.2.0.1,1.2.0.6,114.113.112.1,114.113.112.3,114.113.112.10-114.113.112.13,114.113.112.180
*/


原文地址:https://www.cnblogs.com/zc_0101/p/1673692.html