2010-07-29 78 views
1

我正在处理涉及C#和SQL Server 2008数据库的项目。 在其中一个表中,我有一个字段(nvarchar(15)),它将包含一个IP地址。检查约束以验证IP地址字段

我想添加一个检查约束,它将验证输入值实际上是一个IP地址。

我想使用正则表达式来做到这一点,但似乎默认情况下不支持此功能。我看到有关使用UDF编写customm dll的内容(MSDN tutorial),但我并不真正了解它是如何工作的(即,我应该在哪里放置dll?)

是否存在“简单”方式来添加这样的约束? 欢迎任何解决方案。

在此先感谢!

+1

出于好奇,你是否要在应用程序中验证IP地址,然后再将其插入数据库? – JohnB 2010-07-29 13:10:24

+0

是的,我会的,但正如我在回答Josh K时所说的,其他软件(我们不开发)将访问此数据库,因此它必须足够强大。 – Shimrod 2010-07-29 13:15:49

回答

1

有几种方法可以做到这一点 - 性能最好的方法可能是数据库中的CLR function

这是因为SQL具有相当差的文本操作工具,并且SQL Server中没有本机RegEx。

正如其他人所说,在插入到数据库之前,应用程序可以更好地处理这个问题。

+0

这就是我所要做的。我使用了问题中提供的链接中的方法(http://msdn.microsoft.com/en-us/magazine/cc163473.aspx),现在它可以工作! – Shimrod 2010-07-29 14:47:10

1

它不应该在数据库中处理,它应该首先在应用程序中处理。

然后在数据库中添加一个检查,但将它留给数据库来过滤输入是非常简单的。

+1

我知道这一点,我的数据访问层正在检查它。但是这个数据库可以(也将会)被我们在这里不会开发的其他软件访问,所以我不能只依赖于我的数据访问层。 – Shimrod 2010-07-29 13:15:00

2

我能想到的最简单的方法是创建一个函数,如fnCheckIP,并在约束中使用此函数。

没有必要使用UDF。

create function fnCheckIP(@ip varchar(15)) returns bit 
AS 
begin 
    if (@ip is null) 
     return null 

    declare @num1 int 
    declare @num varchar(15)  
    declare @pos int 
    while (@ip is not null) 
    begin 
     set @pos = IsNull(NullIf(charindex('.', @ip), 0), Len(@ip) + 1) 
     set @num = substring(@ip, 1, @pos - 1) 

     if (isnumeric(@num) = 0) or (not cast(@num as int) between 0 and 255) 
      return cast(0 as bit) 

     if (len(@ip) - @pos <= 0) 
      set @ip = null 
     else   
      set @ip = NullIf(substring(@ip, @pos + 1, len(@ip) - @pos), '') 
    end 

    return cast (1 as bit) 
end 
go 

select dbo.fnCheckIP('127.0.0.1') 
select dbo.fnCheckIP('127.0.0.300') 
0

这可能不是完全实用,但一个方法是将存储转换后的字符串### - ### - ### - ###成二进制(4)的数据类型。让接口与连字符一起讨论,并处理将四个数字转换为二进制和后面(这甚至可以通过一个被计算的列来完成)。有点极端,是的,但是使用二进制(4),您将总是能够把它变成一个IP地址。

0

此解决方案与Paulo's类似,但使用任一方法都需要删除逗号字符,因为isnumeric允许逗号将抛出的转换为int错误。

CREATE FUNCTION fn_ValidateIP 
(
    @ip varchar(255) 
) 
RETURNS int 
AS 
BEGIN 
    DECLARE @Result int = 0 
     IF 
      @ip not like '%,%' and 
      len(@ip) <= 15 and 
      isnumeric(PARSENAME(@ip,4)) = 1 and 
      isnumeric(PARSENAME(@ip,3)) = 1 and 
      isnumeric(PARSENAME(@ip,2)) = 1 and 
      isnumeric(PARSENAME(@ip,1)) = 1 and 
      cast(PARSENAME(@ip,4) as int) between 1 and 255 and 
      cast(PARSENAME(@ip,3) as int) between 0 and 255 and 
      cast(PARSENAME(@ip,2) as int) between 0 and 255 and 
      cast(PARSENAME(@ip,1) as int) between 0 and 255 
      set @Result = 1 
     ELSE 
      set @Result = 0 
    RETURN @Result 
END 

select dbo.fn_ValidateIP('127.0.0.1')