Sqlserver
 sql >> Base de données >  >> RDS >> Sqlserver

Type de données pour stocker l'adresse IP dans SQL Server

La manière techniquement correcte de stocker IPv4 est binaire (4), puisque c'est ce qu'il est réellement (non, pas même un INT32/INT (4), la forme textuelle numérique que nous connaissons et aimons tous (255.255.255.255) étant juste la conversion d'affichage de son contenu binaire).

Si vous le faites de cette façon, vous voudrez que les fonctions soient converties vers et depuis le format d'affichage textuel :

Voici comment convertir le formulaire d'affichage textuel en binaire :

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

Et voici comment reconvertir le binaire en format d'affichage textuel :

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

Voici une démonstration de leur utilisation :

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

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

Enfin, lorsque vous effectuez des recherches et des comparaisons, utilisez toujours la forme binaire si vous souhaitez pouvoir exploiter vos index.

MISE À JOUR :

Je voulais ajouter qu'une façon de résoudre les problèmes de performances inhérents aux UDF scalaires dans SQL Server, tout en conservant la réutilisation du code d'une fonction, consiste à utiliser une iTVF (fonction table en ligne) à la place. Voici comment la première fonction ci-dessus (chaîne en binaire) peut être réécrite en tant qu'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

Le voici dans l'exemple :

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

Et voici comment vous l'utiliseriez dans un INSERT

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