Sql server 类来解析IPv4/IPv6字符串并将其存储为VARBINARY(16)。可以使用同一类将字节[]转换为字符串。如果要在SQL中转换VARBINARY: --SELECT -- dbo.varbinaryToIpString(CAST(0x7F000001 AS VARBINARY(4))) IPv4, -- dbo.varbinaryToIpString(CAST(0x20010DB885A3000000008A2E03707334 AS VARBINARY(16))) IPv6 --ALTER CREATE FUNCTION dbo.varbinaryToIpString ( @varbinaryValue VARBINARY(16) ) RETURNS VARCHAR(39) AS BEGIN IF @varbinaryValue IS NULL RETURN NULL IF DATALENGTH(@varbinaryValue) = 4 BEGIN RETURN CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 1, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 2, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 3, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 4, 1))) END IF DATALENGTH(@varbinaryValue) = 16 BEGIN RETURN sys.fn_varbintohexsubstring(0, @varbinaryValue, 1, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 3, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 5, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 7, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 9, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 11, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 13, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 15, 2) END RETURN 'Invalid' END

Sql server 类来解析IPv4/IPv6字符串并将其存储为VARBINARY(16)。可以使用同一类将字节[]转换为字符串。如果要在SQL中转换VARBINARY: --SELECT -- dbo.varbinaryToIpString(CAST(0x7F000001 AS VARBINARY(4))) IPv4, -- dbo.varbinaryToIpString(CAST(0x20010DB885A3000000008A2E03707334 AS VARBINARY(16))) IPv6 --ALTER CREATE FUNCTION dbo.varbinaryToIpString ( @varbinaryValue VARBINARY(16) ) RETURNS VARCHAR(39) AS BEGIN IF @varbinaryValue IS NULL RETURN NULL IF DATALENGTH(@varbinaryValue) = 4 BEGIN RETURN CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 1, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 2, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 3, 1))) + '.' + CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 4, 1))) END IF DATALENGTH(@varbinaryValue) = 16 BEGIN RETURN sys.fn_varbintohexsubstring(0, @varbinaryValue, 1, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 3, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 5, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 7, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 9, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 11, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 13, 2) + ':' + sys.fn_varbintohexsubstring(0, @varbinaryValue, 15, 2) END RETURN 'Invalid' END,sql-server,tsql,sql-server-2005,types,ip-address,Sql Server,Tsql,Sql Server 2005,Types,Ip Address,由于我想同时处理IPv4和IPv6,因此我使用VARBINARY(16)和以下SQL CLR函数将文本IP地址表示转换为字节和相反的格式: [SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)] public static SqlBytes GetIPAddressBytesFromString (SqlString value) { IPAddress IP; if (IPAddress.

由于我想同时处理
IPv4
IPv6
,因此我使用
VARBINARY(16)
和以下
SQL CLR
函数将
文本
IP地址表示转换为字节和相反的格式:

[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlBytes GetIPAddressBytesFromString (SqlString value)
{
    IPAddress IP;

    if (IPAddress.TryParse(value.Value, out IP))
    {
        return new SqlBytes(IP.GetAddressBytes());
    }
    else
    {
        return new SqlBytes();
    }
}


[SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
public static SqlString GetIPAddressStringFromBytes(SqlBytes value)
{
    string output;

    if (value.IsNull)
    {
        output = "";
    }
    else
    {
        IPAddress IP = new IPAddress(value.Value);
        output = IP.ToString();
    }

    return new SqlString(output);
}

我喜欢沙石的功能。但是我在dbo.fn_convertipaddress-tobinary的代码中发现了一个错误。当您将@delim连接到@ipAddress VARCHAR(39)时,@ipAddress VARCHAR(39)的传入参数太小

SET @ipAddress = @ipAddress + @delim
你可以增加到40。或者最好使用一个更大的新变量并在内部使用。这样你就不会在大的数字上失去最后一对

SELECT dbo.fn_ConvertIpAddressToBinary('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
我正在使用
varchar(15)
到目前为止,一切都对我有效。插入、更新、选择。我刚刚启动了一个具有IP地址的应用程序,尽管我还没有做很多开发工作

以下是select语句:

select * From dbo.Server 
where  [IP] = ('132.46.151.181')
Go

以下答案基于和对此问题的回答,但有以下改进:

  • 将未记录函数(
    sys.fn\u varbintohexsubstring
    fn\u varbintohexstr
    )的使用替换为
  • 将XML“hacks”(
    CAST(“”为XML).value('xs:hexBinary())
    )替换为的
    CONVERT()
  • 修复了实现
    fn_ConvertIpAddressToBinary
    时的错误(如所指出的)
  • 添加次要语法糖
该代码已在SQL Server 2014和SQL Server 2016中进行了测试(请参见末尾的测试用例)

IPAddressVarbinaryToString 将4字节值转换为字符串表示形式,将16字节值转换为字符串表示形式。请注意,此函数不会缩短地址

ALTER FUNCTION dbo.IPAddressVarbinaryToString
(
    @varbinaryValue VARBINARY( 16 )
)
RETURNS VARCHAR(39)
AS
BEGIN
    IF @varbinaryValue IS NULL
        RETURN NULL;
    ELSE IF DATALENGTH( @varbinaryValue ) = 4
        RETURN 
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 1, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 2, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 3, 1 ))) + '.' +
            CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 4, 1 )));
    ELSE IF DATALENGTH( @varbinaryValue ) = 16
        RETURN 
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  1, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  3, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  5, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  7, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  9, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 11, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 13, 2 ), 2 ) + ':' +
            CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 15, 2 ), 2 );

    RETURN 'Invalid';
END
测试用例: IPAddressStringToVarbinary 将和字符串表示形式分别转换为4字节和16字节的二进制值。请注意,此函数能够解析大多数(所有常用的)速记地址表示(例如127…1和2001:db8::1319:370:7348)。 若要强制此函数始终返回16字节二进制值,请在函数末尾取消注释导致0s串联

ALTER FUNCTION [dbo].[IPAddressStringToVarbinary]
(
    @IPAddress VARCHAR( 39 )
)
RETURNS VARBINARY(16) AS
BEGIN

IF @ipAddress IS NULL
    RETURN NULL;

DECLARE @bytes VARBINARY(16), @token VARCHAR(4),
    @vbytes VARBINARY(16) = 0x, @vbzone VARBINARY(2),
    @tIPAddress VARCHAR( 40 ),
    @colIndex TINYINT,
    @delim CHAR(1) = '.',
    @prevColIndex TINYINT = 0,
    @parts TINYINT = 0, @limit TINYINT = 4;

-- Get position if IPV4 delimiter
SET @colIndex = CHARINDEX( @delim, @ipAddress );

-- If not IPV4, then assume IPV6
IF @colIndex = 0
BEGIN
    SELECT @delim = ':', @limit = 8, @colIndex = CHARINDEX( @delim, @ipAddress );

    -- Get number of parts (delimiters)
    WHILE @colIndex > 0
        SELECT @parts += 1, @colIndex = CHARINDEX( @delim, @ipAddress, @colIndex + 1 );

    SET @colIndex = CHARINDEX( @delim, @ipAddress );

    IF @colIndex = 0
        RETURN NULL;
END

-- Add trailing delimiter (need new variable of larger size)
SET @tIPAddress = @IPAddress + @delim;

WHILE @colIndex > 0
BEGIN
    SET @token = SUBSTRING( @tIPAddress, @prevColIndex + 1, @Colindex - @prevColIndex - 1 );

    IF @delim = ':'
    BEGIN
        SELECT @vbzone = CONVERT( VARBINARY(2), RIGHT( '0000' + @token, 4 ), 2 ), @vbytes += @vbzone;

        -- Handles consecutive sections of zeros representation rule (i.e. ::)(https://en.wikipedia.org/wiki/IPv6#Address_representation)
        IF @token = ''
            WHILE @parts + 1 < @limit
                SELECT @vbytes += @vbzone, @parts += 1;
    END
    ELSE
    BEGIN
        SELECT @vbzone = CONVERT( VARBINARY(1), CONVERT( TINYINT, @token )), @vbytes += @vbzone
    END

    SELECT @prevColIndex = @colIndex, @colIndex = CHARINDEX( @delim, @tIPAddress, @colIndex + 1 ) 
END

SET @bytes =
    CASE @delim
        WHEN ':' THEN @vbytes
        ELSE /*0x000000000000000000000000 +*/ @vbytes -- Return IPV4 addresses as 4 byte binary (uncomment leading 0s section to force 16 byte binary)
    END 

RETURN @bytes

END
无效案例

SELECT dbo.IPAddressStringToVarbinary( '0000:0000:0000:0000:0000:0000:0000:0001' ) -- 0x0000000000000000000000000001 (check bug fix)
SELECT dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' ) -- 0x00010002000300400500060070000089
SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' )     -- 0x20010DB885A308D31319000003707348 (check short hand)
SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319:0000:370:7348' ) -- 0x20010DB885A308D31319000003707348
SELECT dbo.IPAddressStringToVarbinary( '192.168.1.72' ) -- 0xC0A80148
SELECT dbo.IPAddressStringToVarbinary( '127...1' ) -- 0x7F000001 (check short hand)
SELECT dbo.IPAddressStringToVarbinary( NULL ) -- NULL
SELECT dbo.IPAddressStringToVarbinary( '' ) -- NULL
-- Check that conversions return original address
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' )) -- '0001:0002:0003:0040:0500:0600:7000:0089' 
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127...1' )) -- 127.0.0.1
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '192.168.1.72' )) -- 192.168.1.72
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' ))     -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1314:0000:370:7348' )) -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3::370:7348' )) -- 2001:0DB8:85A3:08D3:0000:0000:0370:7348
-- This is technically an invalid IPV6 (according to Wikipedia) but it parses correctly
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::370:7348' )) -- 2001:0DB8:0000:0000:1319:0000:0370:7348
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::7348' )) -- 2001:0DB8:0000:0000:0000:1319:0000:7348 (ambiguous address)
SELECT dbo.IPAddressStringToVarbinary( '127.1' ) -- 127.0.0.1 (not supported short-hand)
SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127.1' )) -- 127.0.0.1 (not supported short-hand)
SELECT dbo.IPAddressStringToVarbinary( '0300.0000.0002.0353' ) -- octal byte values
SELECT dbo.IPAddressStringToVarbinary( '0xC0.0x00.0x02.0xEB' ) -- hex values
SELECT dbo.IPAddressStringToVarbinary( 'C0.00.02.EB' ) -- hex values

我们做了很多工作,需要找出哪些IP位于某些子网内。我发现最简单、最可靠的方法是:

  • 在每个名为IPInteger(bigint)的表中添加一个字段(如果无效,则设置IP='0.0.0')
  • 对于较小的表,我使用一个触发器,在更改时更新IPInteger
  • 对于较大的表,我使用存储过程刷新IPInteger

  • 我认为这只在学术意义上是正确的。在不知道海报试图解决的目的和域问题的情况下,我怀疑这会不必要地使与数据的交互复杂化,并可能降低性能。IPv4是一个四字节的有序序列。这就是它的域,在存储格式中是一个BIN(4)。存储格式不会影响性能,因为它是最佳格式。转换函数可能会(因为udf对SQL server很敏感),这可以通过在线或在客户机上进行转换来解决。最后,这种方法有一个显著的优势,即它可以使用索引范围扫描搜索1、2或3类子网中的地址(其中fnBinaryIPv4('132.31.55.00')和fnBinaryIPv4('132.31.55.255'))@RBARYYOUNG I将其存储为整数。您能解释一下将其存储为二进制文件的性能优势吗?@Pacerier:1)请参见前面的评论以获取示例,2)我并没有声称二进制文件比整数更快。我声称A)这是正确的格式(确实如此),B)不会慢一些。是的,你错了,丹不是这么说的。此外,这不是一个讨论论坛,也不适合它。Stackoverflow是一个问答游戏,如果你有问题,请发布。什么是范围?并非所有子网都是8字节。此主机所在网络的IP地址范围是:50.50.50.50/20?整数太大,无法存储0-255的值。看看这个答案:现实地说,我们将看到IPV6。现实地说,我们暂时不会看到2000年,不妨使用两位数的日期来节省几个字节。哦,等等。现在是2020年,谷歌看到大约30%的流量通过IPv6()IPv6。IPv6的长度是非常固定的-128位。除非你谈论的是人类永远不会读取的数据或大量数据,否则这是最好的答案。使用二进制而不是字符串的一个简单原因是:二进制版本允许IP地址的数字范围检查!文本版本没有。这当然取决于所需的使用,但二进制数更有用,因为它们具有实际意义。varchar在数据库中占用的空间明显更多。32位IPv4地址的数字存储需要4个字节,128位IPv6地址的数字存储需要16个字节。同时,IPv4地址需要15个字节才能存储为字符串,IPv6地址可能需要39个字节才能存储为字符串。varbinary(16)是让db ip to country数据库的答案完美运行的方法。往返转换仅显示了0与ipv6(前导和后导)之间的细微差异。在ToBinary()中,查询计划和未标记为确定性的fn_varbintohextr()的使用遇到了一些问题。else.'部分如何:选择@vbzone=convert(varbinary(2),convert(tinyint,@token))?似乎相当。不需要@zone或xml引擎?如果xml引擎以某种方式从“:”中删除,看起来加速效果不错。concat_ws(“.”,(IPAddr&0xFF000000)>>24,(IPAddr&0xFF0000)>>16,(IPAddr&0xFF00)>>8,(IPAddr&0xFF))将包含IP地址的无符号长字符转换为人类可读的形式。@theking2-确实如此
    --SELECT 
    --  dbo.varbinaryToIpString(CAST(0x7F000001 AS VARBINARY(4))) IPv4,
    --  dbo.varbinaryToIpString(CAST(0x20010DB885A3000000008A2E03707334 AS VARBINARY(16))) IPv6
    
    --ALTER 
    CREATE
    FUNCTION dbo.varbinaryToIpString
    (
        @varbinaryValue VARBINARY(16)
    )
    RETURNS VARCHAR(39)
    AS
    BEGIN
        IF @varbinaryValue IS NULL
            RETURN NULL
        IF DATALENGTH(@varbinaryValue) = 4
        BEGIN
            RETURN 
                CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 1, 1))) + '.' +
                CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 2, 1))) + '.' +
                CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 3, 1))) + '.' +
                CONVERT(VARCHAR(3), CONVERT(INT, SUBSTRING(@varbinaryValue, 4, 1)))
        END
        IF DATALENGTH(@varbinaryValue) = 16
        BEGIN
            RETURN 
                sys.fn_varbintohexsubstring(0, @varbinaryValue,  1, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue,  3, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue,  5, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue,  7, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue,  9, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue, 11, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue, 13, 2) + ':' +
                sys.fn_varbintohexsubstring(0, @varbinaryValue, 15, 2)
        END
    
        RETURN 'Invalid'
    END
    
    [SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
    public static SqlBytes GetIPAddressBytesFromString (SqlString value)
    {
        IPAddress IP;
    
        if (IPAddress.TryParse(value.Value, out IP))
        {
            return new SqlBytes(IP.GetAddressBytes());
        }
        else
        {
            return new SqlBytes();
        }
    }
    
    
    [SqlFunction(DataAccess = DataAccessKind.None, IsDeterministic = true)]
    public static SqlString GetIPAddressStringFromBytes(SqlBytes value)
    {
        string output;
    
        if (value.IsNull)
        {
            output = "";
        }
        else
        {
            IPAddress IP = new IPAddress(value.Value);
            output = IP.ToString();
        }
    
        return new SqlString(output);
    }
    
    SET @ipAddress = @ipAddress + @delim
    
    SELECT dbo.fn_ConvertIpAddressToBinary('ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff')
    
    select * From dbo.Server 
    where  [IP] = ('132.46.151.181')
    Go
    
    ALTER FUNCTION dbo.IPAddressVarbinaryToString
    (
        @varbinaryValue VARBINARY( 16 )
    )
    RETURNS VARCHAR(39)
    AS
    BEGIN
        IF @varbinaryValue IS NULL
            RETURN NULL;
        ELSE IF DATALENGTH( @varbinaryValue ) = 4
            RETURN 
                CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 1, 1 ))) + '.' +
                CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 2, 1 ))) + '.' +
                CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 3, 1 ))) + '.' +
                CONVERT( VARCHAR(3), CONVERT(TINYINT, SUBSTRING( @varbinaryValue, 4, 1 )));
        ELSE IF DATALENGTH( @varbinaryValue ) = 16
            RETURN 
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  1, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  3, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  5, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  7, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue,  9, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 11, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 13, 2 ), 2 ) + ':' +
                CONVERT( VARCHAR(4), SUBSTRING( @varbinaryValue, 15, 2 ), 2 );
    
        RETURN 'Invalid';
    END
    
    SELECT dbo.IPAddressVarbinaryToString(0x00000000000000000000000000000000) -- 0000:0000:0000:0000:0000:0000:0000:0000 (no address shortening)
    SELECT dbo.IPAddressVarbinaryToString(0x00010002000300400500060070000089) -- 0001:0002:0003:0040:0500:0600:7000:0089
    SELECT dbo.IPAddressVarbinaryToString(0xC0A80148) -- 255.168.1.72
    SELECT dbo.IPAddressVarbinaryToString(0x7F000001) -- 127.0.0.1 (no address shortening)
    SELECT dbo.IPAddressVarbinaryToString(NULL) -- NULL
    
    ALTER FUNCTION [dbo].[IPAddressStringToVarbinary]
    (
        @IPAddress VARCHAR( 39 )
    )
    RETURNS VARBINARY(16) AS
    BEGIN
    
    IF @ipAddress IS NULL
        RETURN NULL;
    
    DECLARE @bytes VARBINARY(16), @token VARCHAR(4),
        @vbytes VARBINARY(16) = 0x, @vbzone VARBINARY(2),
        @tIPAddress VARCHAR( 40 ),
        @colIndex TINYINT,
        @delim CHAR(1) = '.',
        @prevColIndex TINYINT = 0,
        @parts TINYINT = 0, @limit TINYINT = 4;
    
    -- Get position if IPV4 delimiter
    SET @colIndex = CHARINDEX( @delim, @ipAddress );
    
    -- If not IPV4, then assume IPV6
    IF @colIndex = 0
    BEGIN
        SELECT @delim = ':', @limit = 8, @colIndex = CHARINDEX( @delim, @ipAddress );
    
        -- Get number of parts (delimiters)
        WHILE @colIndex > 0
            SELECT @parts += 1, @colIndex = CHARINDEX( @delim, @ipAddress, @colIndex + 1 );
    
        SET @colIndex = CHARINDEX( @delim, @ipAddress );
    
        IF @colIndex = 0
            RETURN NULL;
    END
    
    -- Add trailing delimiter (need new variable of larger size)
    SET @tIPAddress = @IPAddress + @delim;
    
    WHILE @colIndex > 0
    BEGIN
        SET @token = SUBSTRING( @tIPAddress, @prevColIndex + 1, @Colindex - @prevColIndex - 1 );
    
        IF @delim = ':'
        BEGIN
            SELECT @vbzone = CONVERT( VARBINARY(2), RIGHT( '0000' + @token, 4 ), 2 ), @vbytes += @vbzone;
    
            -- Handles consecutive sections of zeros representation rule (i.e. ::)(https://en.wikipedia.org/wiki/IPv6#Address_representation)
            IF @token = ''
                WHILE @parts + 1 < @limit
                    SELECT @vbytes += @vbzone, @parts += 1;
        END
        ELSE
        BEGIN
            SELECT @vbzone = CONVERT( VARBINARY(1), CONVERT( TINYINT, @token )), @vbytes += @vbzone
        END
    
        SELECT @prevColIndex = @colIndex, @colIndex = CHARINDEX( @delim, @tIPAddress, @colIndex + 1 ) 
    END
    
    SET @bytes =
        CASE @delim
            WHEN ':' THEN @vbytes
            ELSE /*0x000000000000000000000000 +*/ @vbytes -- Return IPV4 addresses as 4 byte binary (uncomment leading 0s section to force 16 byte binary)
        END 
    
    RETURN @bytes
    
    END
    
    SELECT dbo.IPAddressStringToVarbinary( '0000:0000:0000:0000:0000:0000:0000:0001' ) -- 0x0000000000000000000000000001 (check bug fix)
    SELECT dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' ) -- 0x00010002000300400500060070000089
    SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' )     -- 0x20010DB885A308D31319000003707348 (check short hand)
    SELECT dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319:0000:370:7348' ) -- 0x20010DB885A308D31319000003707348
    SELECT dbo.IPAddressStringToVarbinary( '192.168.1.72' ) -- 0xC0A80148
    SELECT dbo.IPAddressStringToVarbinary( '127...1' ) -- 0x7F000001 (check short hand)
    SELECT dbo.IPAddressStringToVarbinary( NULL ) -- NULL
    SELECT dbo.IPAddressStringToVarbinary( '' ) -- NULL
    -- Check that conversions return original address
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '0001:0002:0003:0040:0500:0600:7000:0089' )) -- '0001:0002:0003:0040:0500:0600:7000:0089' 
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127...1' )) -- 127.0.0.1
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '192.168.1.72' )) -- 192.168.1.72
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1319::370:7348' ))     -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3:1314:0000:370:7348' )) -- 2001:0db8:85a3:08d3:1319:0000:0370:7348
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8:85a3:8d3::370:7348' )) -- 2001:0DB8:85A3:08D3:0000:0000:0370:7348
    -- This is technically an invalid IPV6 (according to Wikipedia) but it parses correctly
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::370:7348' )) -- 2001:0DB8:0000:0000:1319:0000:0370:7348
    
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '2001:db8::1319::7348' )) -- 2001:0DB8:0000:0000:0000:1319:0000:7348 (ambiguous address)
    SELECT dbo.IPAddressStringToVarbinary( '127.1' ) -- 127.0.0.1 (not supported short-hand)
    SELECT dbo.IPAddressVarbinaryToString( dbo.IPAddressStringToVarbinary( '127.1' )) -- 127.0.0.1 (not supported short-hand)
    SELECT dbo.IPAddressStringToVarbinary( '0300.0000.0002.0353' ) -- octal byte values
    SELECT dbo.IPAddressStringToVarbinary( '0xC0.0x00.0x02.0xEB' ) -- hex values
    SELECT dbo.IPAddressStringToVarbinary( 'C0.00.02.EB' ) -- hex values
    
        ALTER FUNCTION [dbo].[IP_To_INT ]
        ( 
            @IP CHAR(15) 
        ) 
        RETURNS BIGINT 
        AS 
        BEGIN 
            DECLARE @IntAns BIGINT, 
                @block1 BIGINT, 
                @block2 BIGINT, 
                @block3 BIGINT, 
                @block4 BIGINT, 
                @base BIGINT 
         
            SELECT 
                @block1 = CONVERT(BIGINT, PARSENAME(@IP, 4)), 
                @block2 = CONVERT(BIGINT, PARSENAME(@IP, 3)), 
                @block3 = CONVERT(BIGINT, PARSENAME(@IP, 2)), 
                @block4 = CONVERT(BIGINT, PARSENAME(@IP, 1)) 
         
            IF (@block1 BETWEEN 0 AND 255) 
                AND (@block2 BETWEEN 0 AND 255) 
                AND (@block3 BETWEEN 0 AND 255) 
                AND (@block4 BETWEEN 0 AND 255) 
            BEGIN      
                SET @base = CONVERT(BIGINT, @block1 * 16777216)
                SET @IntAns = @base +  
                    (@block2 * 65536) +  
                    (@block3 * 256) + 
                    (@block4) 
            END 
            ELSE 
                SET @IntAns = -1 
            RETURN @IntAns 
        END