What datatype should I choose for storing an IP Address in a SQL Server?
By selecting the right datatype would it be easy enough to filter by IP address then?
What datatype should I choose for storing an IP Address in a SQL Server?
By selecting the right datatype would it be easy enough to filter by IP address then?
As I want to handle both
IPv4
andIPv6
, I am usingVARBINARY(16)
and the followingSQL CLR
functions to convert thetext
IP address presentation to bytes and the reverse:I'm using
varchar(15)
so far everything is working for me. Insert, Update, Select. I have just started an app that has IP Addresses, though I have not done much dev work yet.Here is the select statement:
The technically correct way to store IPv4 is Binary(4), since that is what it actually is (no, not even an INT32/INT(4)), the numeric textual form that we all know and love (255.255.255.255) being just the display conversion of it's binary content.
If you do it this way, you will want functions to convert to and from the textual-display format:
Here's how to convert the textual display form to binary:
And here's how to convert the binary back to the textual display form:
Here's a demo of how to use them:
Finally, when doing lookups and compares, always use the binary form if you want to be able to leverage your indexes.
UPDATE:
I wanted to add that one way to address the inherent performance problems of scalar UDF's in SQL Server, but still retain the code-reuse of a function is to use an iTVF (inline table-valued function) instead. Here's how the first function above (string to binary) can be re-written as an iTVF:
Here's it in the example:
And here's how you would use it in an INSERT
Here is some code to convert either IPV4 or IPv6 in varchar format to binary(16) and back. This is the smallest form I could think of. It should index well and provide a relatively easy way to filter on subnets. Requires SQL Server 2005 or later. Not sure it's totally bulletproof. Hope this helps.
I like the functions of SandRock. But I found an error in the code of dbo.fn_ConvertIpAddressToBinary. The incoming parameter of @ipAddress VARCHAR(39) is too small when you concat the @delim to it.
You can increase it to 40. Or better yet use a new variable that is bigger and use that internally. That way you don't lose the last pair on large numbers.
Thanks RBarry. I'm putting together an IP block allocation system and storing as binary is the only way to go.
I'm storing the CIDR representation (ex: 192.168.1.0/24) of the IP block in a varchar field, and using 2 calculated fields to hold the binary form of the start and end of the block. From there, I can run fast queries to see if a given block as already been allocated or is free to assign.
I modified your function to calculate the ending IP Address like so: