sql >> Databasteknik >  >> RDS >> Sqlserver

Datatyp för lagring av ip-adress i SQL Server

Det tekniskt korrekta sättet att lagra IPv4 är binärt(4), eftersom det är vad det faktiskt är (nej, inte ens en INT32/INT(4), den numeriska textformen som vi alla känner och älskar (255.255.255.255) är bara visningskonverteringen av dess binära innehåll).

Om du gör det på detta sätt vill du att funktioner ska konverteras till och från textvisningsformatet:

Så här konverterar du textvisningsformuläret till binärt:

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

Och så här konverterar du binären tillbaka till textvisningsformen:

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

Här är en demonstration av hur du använder dem:

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

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

Slutligen, när du gör uppslagningar och jämförelser, använd alltid den binära formen om du vill kunna utnyttja dina index.

UPPDATERING:

Jag ville tillägga att ett sätt att ta itu med de inneboende prestandaproblemen för skalära UDF:er i SQL Server, men ändå behålla kodåteranvändningen av en funktion är att använda en iTVF (inline table-valued function) istället. Så här kan den första funktionen ovan (sträng till binär) skrivas om 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

Här är det i exemplet:

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

Och här är hur du skulle använda det i en INSERT

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


  1. Motsvarar Oracles externa tabeller i SQL Server

  2. Hur kan jag returnera pivottabellutdata i MySQL?

  3. Hur man automatiserar datainsamling på SQL Server Database Growth

  4. Åtgärda felet "ORA-01790:uttryck måste ha samma datatyp som motsvarande uttryck"