sql >> Database >  >> RDS >> Sqlserver

Gegevenstype voor het opslaan van ip-adres in SQL Server

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'))


  1. Mijn PostgreSQL-database heeft onvoldoende schijfruimte

  2. Verschil in het omgaan met de spaties tussen Oracle en SQL Server

  3. Meerdere zoekopdrachten en resultaten naast elkaar bekijken in SQL Server Management Studio (SSMS) - SQL Server / TSQL-zelfstudie, deel 14

  4. Toon alle query's die naar een Oracle-database komen