SQL CLR Function 查詢範圍 IP

SQL CLR Function 查詢範圍 IP

上一篇【用 SQL 語法查詢符合條件範圍的 IP】中的 IP2INT 的 SQL 語法實在是太醜陋了,所以利用 SQL 可呼叫 CLR 的方式來撰寫查詢。

1. 用 C# 撰寫 SQL Function,請自行編譯成 IPUtility.dll

  1. using System;
  2. using System.Data.SqlTypes;
  3. using Microsoft.SqlServer.Server;
  4. public class IPUtility
  5. {
  6. [SqlFunction]
  7. public static SqlInt32 IsInRange(SqlString ip, SqlString startIP, SqlString endIP)
  8. {
  9. if (IPToLong(startIP) <= IPToLong(ip) && IPToLong(ip) <= IPToLong(endIP) )
  10. {
  11. return 1;
  12. }
  13. return 0;
  14. }
  15. private static long IPToLong(SqlString ip)
  16. {
  17. string [ ] ipClass = ip.ToString ( ).Split ( );
  18. string strhexip = string.Format ( "{0:X2}{1:X2}{2:X2}{3:X2}", int.Parse (ipClass[ 0 ] ), int.Parse (ipClass[ 1 ] ), int.Parse (ipClass[ 2 ] ), int.Parse (ipClass[ 3 ] ) );
  19. return Convert.ToInt64 (strhexip, 16 );
  20. }
  21. }

2. 在 SQL 引入 IPUtility 並建立 Function

  1. -- Enable CLR integration (啟動 SQL Server 2005 CLR 功能)
  2. sp_configure 'clr enabled', 1
  3. GO
  4. RECONFIGURE
  5. GO
  6. -- Register Assembly (註冊組件)
  7. USE master
  8. CREATE ASSEMBLY IPUtility
  9. FROM 'C:\TMP\IPUtility.dll' -- 請依照 dll 放置位置填寫
  10. WITH PERMISSION_SET = Safe
  11. GO
  12. ---- Drop assembly
  13. --DROP ASSEMBLY IPUtility
  14. --GO
  15. -- Create the managed user-defined function
  16. USE master
  17. GO
  18. CREATE FUNCTION dbo.IsInRange
  19. (
  20. @IP nvarchar( 15 ), @startIP nvarchar( 15 ), @endIP nvarchar( 15 ) -- 需要三參數: 比對 IP, 範圍起始 IP , 範圍結束 IP
  21. )
  22. RETURNS int
  23. AS EXTERNAL NAME IPUtility.IPUtility.IsInRange
  24. GO
  25. -- Test Run (測試 Function)
  26. DECLARE @IPTable TABLE (IP nvarchar( 15 ) )
  27. INSERT INTO @IPTable VALUES ( N'172.16.57.103' )
  28. INSERT INTO @IPTable VALUES ( N'172.16.58.103' )
  29. INSERT INTO @IPTable VALUES ( N'172.16.59.103' )
  30. INSERT INTO @IPTable VALUES ( N'172.16.60.103' )
  31. INSERT INTO @IPTable VALUES ( N'172.16.61.103' )
  32. INSERT INTO @IPTable VALUES ( N'172.16.62.103' )
  33. SELECT IP
  34. FROM @IPTable
  35. WHERE dbo.IsInRange(IP, '172.16.58.103', '172.16.61.109' ) = 1
  36. GO

OUTPUT:

172.16.58.103
172.16.59.103
172.16.60.103
172.16.61.103