SQL Server 2008 R2标量函数转换及IP零填充代码逻辑解析
没问题,我帮你把这段IP补零的逻辑转换成适配SQL Server 2008 R2的标量函数,同时把每一步CASE的修改逻辑给你拆解清楚:
一、转换后的标量函数代码
CREATE FUNCTION dbo.FormatIPForSorting ( @ip NVARCHAR(15) ) RETURNS NVARCHAR(15) AS BEGIN -- 处理第一个IP段 SELECT @ip = CASE WHEN CHARINDEX('.', @ip) < 4 THEN STUFF(@ip, 1, 0, REPLICATE('0', 4 - CHARINDEX('.', @ip, 1))) ELSE @ip END -- 处理第二个IP段 SELECT @ip = CASE WHEN CHARINDEX('.', @ip, 5) < 8 THEN STUFF(@ip, 5, 0, REPLICATE('0', 8 - CHARINDEX('.', @ip, 5))) ELSE @ip END -- 处理第三个IP段 SELECT @ip = CASE WHEN CHARINDEX('.', @ip, 9) < 12 THEN STUFF(@ip, 9, 0, REPLICATE('0', 12 - CHARINDEX('.', @ip, 9))) ELSE @ip END -- 处理第四个IP段 SELECT @ip = CASE WHEN LEN(@ip) < 15 THEN STUFF(@ip, 13, 0, REPLICATE('0', 15 - LEN(@ip))) ELSE @ip END RETURN @ip END GO
你可以直接执行这段代码创建函数,调用的时候用SELECT dbo.FormatIPForSorting('2.18.4.14')就能得到补全后的002.018.004.014。
二、CASE步骤的修改逻辑详解
这段代码的核心是把IP的四个段都补成3位(比如2变成002,18变成018),这样字符串的字典序就和IP的数值顺序一致了。每一步CASE的作用如下:
第一个CASE:处理第一个IP段
CHARINDEX('.', @ip)会找到第一个.的位置。正常情况下,3位的IP段加.应该占4个字符(比如123.),所以如果第一个.的位置小于4,说明第一个段不足3位。我们用4 - CHARINDEX('.', @ip, 1)算出需要补的0的数量,再用STUFF在字符串开头插入这些0,把第一个段补成3位。比如2.18.4.14会变成002.18.4.14。第二个CASE:处理第二个IP段
CHARINDEX('.', @ip, 5)是从第5位开始找第二个.(因为第一个段补成3位加.正好占4位,第5位是第二个段的起始位置)。正常第二个段补成3位加.后,第二个.的位置应该是第8位(比如002.123.),如果位置小于8,说明第二个段不足3位。计算需要补的0的数量后,用STUFF在第5位插入这些0,把第二个段补成3位。比如002.18.4.14会变成002.018.4.14。第三个CASE:处理第三个IP段
CHARINDEX('.', @ip, 9)从第9位开始找第三个.(前两个段各3位加.共占8位,第9位是第三个段的起始位置)。正常第三个段补成3位加.后,第三个.的位置应该是第12位(比如002.123.456.),如果位置小于12,说明第三个段不足3位。同样用STUFF在第9位插入0,把第三个段补成3位。比如002.018.4.14会变成002.018.004.14。第四个CASE:处理第四个IP段
前面三个段补好后,xxx.xxx.xxx.已经占了12个字符,加上第四个段3位正好是15位。如果当前字符串长度小于15,说明第四个段不足3位,计算需要补的0的数量后,用STUFF在第13位(第三个.之后的位置)插入这些0,把第四个段补成3位。比如002.018.004.14会变成002.018.004.014。
三、返回值说明
不管是原代码还是转换后的标量函数,返回的都是标量值——也就是单个NVARCHAR(15)类型的字符串,不是表。原代码最后SELECT @a输出的就是补全后的IP字符串,标量函数每次调用也只会返回一个这样的结果。
内容的提问来源于stack exchange,提问作者Ephedra

