Два небольших улучшения.
- Записывается как встроенная табличная функция
- Обходит тот факт, что
PARSENAME
является недетерминированным
Функция:
CREATE FUNCTION dbo.IPv4ToInt
(
@ip varchar(15)
)
RETURNS TABLE
WITH SCHEMABINDING
AS
RETURN
SELECT
IPv4Int =
CASE
WHEN LEN(@ip) - LEN(REPLACE(@ip COLLATE Latin1_General_BIN2, '.', '')) = 3
AND @ip COLLATE Latin1_General_BIN2 NOT LIKE '%[^.0-9]%'
AND @ip COLLATE Latin1_General_BIN2 LIKE '[0-9]%.[0-9]%.[0-9]%.[0-9]%'
THEN
CONVERT
(
integer,
(
CONVERT(binary(1), CONVERT(tinyint, SUBSTRING(@ip COLLATE Latin1_General_BIN2, 1, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) - 1)))
+
CONVERT(binary(1), CONVERT(tinyint, SUBSTRING(@ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) - (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) - 1)))
+
CONVERT(binary(1), CONVERT(tinyint, SUBSTRING(@ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) + 1, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) + 1)) - (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) - 1)))
+
CONVERT(binary(1), CONVERT(tinyint, SUBSTRING(@ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) + 1)) + 1, LEN(@ip) - (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, (CHARINDEX('.', @ip COLLATE Latin1_General_BIN2, 1)) + 1)) + 1)))))
)
)
ELSE NULL
END;
Показать свойства функции:
SELECT
IsDeterministic = OBJECTPROPERTYEX(OBJECT_ID(N'dbo.IPv4ToInt', N'IF'), 'IsDeterministic'),
IsSystemVerified = OBJECTPROPERTYEX(OBJECT_ID(N'dbo.IPv4ToInt', N'IF'), 'IsSystemVerified'),
IsPrecise = OBJECTPROPERTYEX(OBJECT_ID(N'dbo.IPv4ToInt', N'IF'), 'IsPrecise');
Пример использования:
DECLARE @Data TABLE
(
IPv4 varchar(15) NULL
);
INSERT @Data
(IPv4)
VALUES
('192.168.0.3'),
('0.0.0.0'),
('10.0.16.129'),
('255.255.255.255');
SELECT *
FROM @Data AS d
CROSS APPLY dbo.IPv4ToInt(d.IPv4) AS ipti;