De technisch correcte manier om IPv4 op te slaan is binair(4), want dat is het eigenlijk (nee, zelfs geen INT32/INT(4), de numerieke tekstvorm die we allemaal kennen en waarderen (255.255.255.255) is gewoon de weergaveconversie van de binaire inhoud).
Als je het op deze manier doet, wil je dat functies worden geconverteerd naar en van het tekstuele weergaveformaat:
Zo converteert u de tekstuele weergavevorm naar binair:
CREATE FUNCTION dbo.fnBinaryIPv4(@ip AS VARCHAR(15)) RETURNS BINARY(4)
AS
BEGIN
DECLARE @bin AS BINARY(4)
SELECT @bin = CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))
RETURN @bin
END
go
En zo converteert u het binaire bestand terug naar de tekstuele weergavevorm:
CREATE FUNCTION dbo.fnDisplayIPv4(@ip AS BINARY(4)) RETURNS VARCHAR(15)
AS
BEGIN
DECLARE @str AS VARCHAR(15)
SELECT @str = CAST( CAST( SUBSTRING( @ip, 1, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 2, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 3, 1) AS INTEGER) AS VARCHAR(3) ) + '.'
+ CAST( CAST( SUBSTRING( @ip, 4, 1) AS INTEGER) AS VARCHAR(3) );
RETURN @str
END;
go
Hier is een demo van hoe je ze kunt gebruiken:
SELECT dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go
SELECT dbo.fnDisplayIPv4( 0xC04144C9 )
-- should return '192.65.68.201'
go
Tot slot, wanneer u opzoekt en vergelijkt, gebruik dan altijd de binaire vorm als u uw indexen wilt benutten.
BIJWERKEN:
Ik wilde toevoegen dat een manier om de inherente prestatieproblemen van scalaire UDF's in SQL Server aan te pakken, maar toch het hergebruik van code van een functie te behouden, is om in plaats daarvan een iTVF (inline tabelwaardefunctie) te gebruiken. Hier is hoe de eerste functie hierboven (string naar binair) kan worden herschreven als een iTVF:
CREATE FUNCTION dbo.itvfBinaryIPv4(@ip AS VARCHAR(15)) RETURNS TABLE
AS RETURN (
SELECT CAST(
CAST( CAST( PARSENAME( @ip, 4 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 3 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 2 ) AS INTEGER) AS BINARY(1))
+ CAST( CAST( PARSENAME( @ip, 1 ) AS INTEGER) AS BINARY(1))
AS BINARY(4)) As bin
)
go
Hier is het in het voorbeeld:
SELECT bin FROM dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go
En zo zou je het gebruiken in een INSERT
INSERT INTo myIpTable
SELECT {other_column_values,...},
(SELECT bin FROM dbo.itvfBinaryIPv4('192.65.68.201'))