sql >> Database teknologi >  >> RDS >> Sqlserver

Datatype til lagring af ip-adresse i SQL Server

Den teknisk korrekte måde at gemme IPv4 på er binær(4), da det er, hvad den faktisk er (nej, ikke engang en INT32/INT(4), idet den numeriske tekstform, som vi alle kender og elsker (255.255.255.255), er bare visningskonverteringen af ​​dets binære indhold).

Hvis du gør det på denne måde, vil du have funktioner til at konvertere til og fra tekstvisningsformatet:

Sådan konverterer du den tekstuelle visningsform til binær:

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

Og her er, hvordan du konverterer det binære tilbage til den tekstuelle visningsform:

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

Her er en demo af, hvordan du bruger dem:

SELECT dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

SELECT dbo.fnDisplayIPv4( 0xC04144C9 )
-- should return '192.65.68.201'
go

Til sidst, når du foretager opslag og sammenligninger, skal du altid bruge den binære form, hvis du vil være i stand til at udnytte dine indekser.

OPDATERING:

Jeg ønskede at tilføje, at en måde at løse de iboende ydeevneproblemer ved skalære UDF'er i SQL Server, men stadig bevare kodegenbrug af en funktion, er at bruge en iTVF (inline table-valued function) i stedet. Sådan kan den første funktion ovenfor (streng til binær) omskrives som en 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

Her er det i eksemplet:

SELECT bin FROM dbo.fnBinaryIPv4('192.65.68.201')
--should return 0xC04144C9
go

Og her er, hvordan du ville bruge det i en INSERT

INSERT INTo myIpTable
SELECT {other_column_values,...},
       (SELECT bin FROM dbo.itvfBinaryIPv4('192.65.68.201'))


  1. Fix "Kan ikke installere i Homebrew på ARM-processor i Intels standardpræfiks (/usr/local)!"

  2. Udforskning af lavprioritetslås-venteindstillinger i SQL Server 2014 CTP1

  3. Minus vs Undtagen forskel i ORACLE/SQL-server

  4. Forbedring af top/top faldende medianløsning