2010-07-29 4 views
1

Я работаю над проектом с C# и базой данных SQL Server 2008. В одной из таблиц у меня есть поле (nvarchar(15)), которое будет содержать IP-адрес.Проверить ограничение для проверки поля IP-адреса

Я хотел бы добавить контрольное ограничение, которое будет проверять, что входное значение фактически является IP-адресом.

Я хотел использовать регулярное выражение для этого, но кажется, что эта функция не поддерживается по умолчанию. Я видел вещи о написании dll customm с UDF внутри (MSDN tutorial), но я действительно не понимаю, как это работает (например, где я должен разместить dll?)

Есть ли «простой» способ добавить такой ограничение? Любые решения приветствуются.

Заранее благодарен!

+1

Из любопытства вы собираетесь проверить IP-адрес в своем приложении, прежде чем вставлять его в БД? – JohnB

+0

Да, но, как я уже сказал в своем ответе Джошу К, другое программное обеспечение (мы не разрабатываем) будет иметь доступ к этой базе данных, поэтому оно должно быть достаточно сильным в одиночку. – Shimrod

ответ

1

Существует несколько способов сделать это - наиболее эффективным может быть CLR function в базе данных.

Это связано с тем, что SQL имеет довольно плохие инструменты для обработки текста и не имеет собственного RegEx в SQL Server.

Как говорили другие, это лучше обрабатывать приложение перед вставкой в ​​БД.

+0

Вот что я закончил. Я использовал метод, который находится в ссылке, указанной в вопросе (http://msdn.microsoft.com/en-us/magazine/cc163473.aspx), и теперь он работает! – Shimrod

1

Его нельзя обрабатывать в базе данных, его следует обрабатывать в первую очередь в приложении.

В этом случае нет никакого вреда, а затем добавление проверки в базу данных, но отказ от него в БД для ввода фильтра очень отрывочно.

+1

Я знаю это, и мой уровень доступа к данным проверяет его в первую очередь. Но к этой базе данных можно (и будет) обращаться к другому программному обеспечению, которое мы не будем развивать здесь, поэтому я не могу полагаться только на свой уровень доступа к данным. – Shimrod

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) тип данных. Позвольте интерфейсу суетиться с дефисами и иметь дело с преобразованием четырех чисел в двоичные и обратно (и это, возможно, даже может быть сделано с помощью caluclated column.) Немного экстремальный, да, но с двоичным (4) вы будете всегда be способный превратить его в IP-адрес.

0

Это решение похоже на Paulo's, но при любом подходе потребуется избавиться от символа запятой, поскольку isnumeric разрешает запятые, которые будут бросать приведение в int error.

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') 

 Смежные вопросы

  • Нет связанных вопросов^_^