I recently answered a with question with the code below. My question is, what is the best way to convert a binary [string] to int so I can remove one of the recursive ctes. Eg SELECT CAST('0011' as binary(1)) I am looking for 3 not 48
DECLARE @Subnet varchar(15)
DECLARE @bits int
DECLARE @IP TABLE (IPAddr varchar(15), Running binary(8))
INSERT @IP
SELECT '10.10.19.2', NULL UNION -- 00001010 00001010 00010011 00000010
SELECT '10.10.10.5', NULL UNION -- 00001010 00001010 00001010 00000101
SELECT '10.10.11.2', NULL -- 00001010 00001010 00001011 00000010
SET @Subnet = '10.10.10.0' -- 00001010 00001010 00001010 00000000
-- 10.10.11.2 is part of the 10.10.10.0 CIDR block
DECLARE @Fun bigint
SET @Fun = CAST(CAST(16777216 as bigint) * PARSENAME(@Subnet, 4)
+ 65536 * PARSENAME(@Subnet, 3)
+ 256 * PARSENAME(@Subnet, 2)
+ PARSENAME(@Subnet, 1) as binary(8))
UPDATE @IP
SET Running = CAST(CAST(16777216 as bigint) * PARSENAME(IPAddr, 4)
+ 65536 * PARSENAME(IPAddr, 3)
+ 256 * PARSENAME(IPAddr, 2)
+ PARSENAME(IPAddr, 1) as binary(8))
-- determine significant bits
;WITH bits AS (
SELECT i = cast(1 AS bigint), j = 0
UNION ALL
SELECT i * 2, j + 1
FROM bits
WHERE i <= 2147483648 AND @Fun & i = 0
)
SELECT @bits = MIN(32 - j) FROM bits
-- determine subnet mask
DECLARE @Scissors bigint
SELECT @Scissors = 4294967296 - POWER(CAST(2 AS bigint), CAST(32 AS bigint) - @bits)
SELECT @Subnet [Subnet], COUNT(IPAddr) [Count]
FROM @IP
WHERE @Scissors & Running = @Fun