Die technisch korrekte Art, IPv4 zu speichern, ist binär(4), da es das tatsächlich ist (nein, nicht einmal ein INT32/INT(4), wobei die numerische Textform, die wir alle kennen und lieben (255.255.255.255), gerecht ist die Anzeigeumwandlung seines binären Inhalts).
Wenn Sie dies auf diese Weise tun, möchten Sie, dass Funktionen in das und aus dem Textanzeigeformat konvertieren:
So konvertieren Sie die textuelle Anzeigeform in eine binäre:
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
Und so konvertieren Sie die Binärdatei zurück in die Textanzeigeform:
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 ist eine Demo, wie man sie benutzt:
SELECT dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go
SELECT dbo.fnDisplayIPv4( 0xC04144C9 )
-- should return '192.65.68.201'
go
Schließlich sollten Sie beim Suchen und Vergleichen immer die binäre Form verwenden, wenn Sie Ihre Indizes nutzen möchten.
UPDATE:
Ich wollte hinzufügen, dass eine Möglichkeit, die inhärenten Leistungsprobleme von skalaren UDFs in SQL Server anzugehen, aber dennoch die Codewiederverwendung einer Funktion beizubehalten, darin besteht, stattdessen eine iTVF (Inline-Tabellenwertfunktion) zu verwenden. So kann die erste obige Funktion (String zu Binär) als iTVF umgeschrieben werden:
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 ist es im Beispiel:
SELECT bin FROM dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go
Und so würden Sie es in einem INSERT verwenden
INSERT INTo myIpTable
SELECT {other_column_values,...},
(SELECT bin FROM dbo.itvfBinaryIPv4('192.65.68.201'))