sql >> Base de Datos >  >> RDS >> Sqlserver

Tipo de datos para almacenar la dirección IP en SQL Server

La forma técnicamente correcta de almacenar IPv4 es binario(4), ya que eso es lo que realmente es (no, ni siquiera un INT32/INT(4), siendo la forma textual numérica que todos conocemos y amamos (255.255.255.255) la conversión de visualización de su contenido binario).

Si lo hace de esta manera, querrá funciones para convertir hacia y desde el formato de visualización de texto:

Aquí se explica cómo convertir el formulario de visualización de texto a binario:

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

Y así es como convertir el binario de nuevo a la forma de visualización textual:

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

Aquí hay una demostración de cómo usarlos:

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

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

Finalmente, al realizar búsquedas y comparaciones, utilice siempre el formato binario si desea poder aprovechar sus índices.

ACTUALIZAR:

Quería agregar que una forma de abordar los problemas de rendimiento inherentes de las UDF escalares en SQL Server, pero aún así conservar la reutilización de código de una función, es usar una iTVF (función con valores de tabla en línea) en su lugar. Así es como la primera función anterior (cadena a binario) se puede reescribir como un 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

Aquí está en el ejemplo:

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

Y así es como lo usaría en un INSERT

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