Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Базы данных и репортинг > ip адреса


Автор: sgentstuff 24.7.2006, 11:02
В БД MSSQL хранятся ip адреса в поле ip типа varchar в таком формате:
    [225.255.255.2]
    [225.255.255.3]
    [225.255.255.4]
    [225.255.255.5]
    [225.255.255.6]
Мне нужно получить список адресов между  [225.255.255.6] и [225.255.255.3], как это сделать?

 

Автор: kostas 24.7.2006, 11:33
В MSSQL есть встроенные фукнции для конвертации длинного формата IP в короткий integer и наоборот - INET_ATON и INET_NTOA. Таким образом можно будет вытащить IP адреса из необходимого диапазона. Вообще я бы хранил изначально именно в числовом формате, т.к. и места требует меньше и работать удобней. 

Автор: sgentstuff 24.7.2006, 12:47
можно пример? 

Автор: comtat 24.7.2006, 12:48
Как сказал, kostas, так делать лучше и правильнее,
таким же образом можно хранить еще и маски 

Автор: sgentstuff 24.7.2006, 12:50
    [*1]
    [*2]
    [*3]
 

Автор: comtat 24.7.2006, 12:54
Код

SELECT INET_NTOA(address), INET_NTOA(mask), rule_id from `Nets`


Таблица Nets
address | mask |
3558234880 | 0 

Автор: sgentstuff 24.7.2006, 12:59
вот такую ошибку пишет
'INET_NTOA' is not a recognized function name. 

Автор: kostas 24.7.2006, 20:14
база данных точно mSsql ? может вы путаете с mYsql... и какая версия? 

Автор: sgentstuff 25.7.2006, 06:41
Цитата(kostas @ 24.7.2006,  20:14)
база данных точно mSsql ? может вы путаете с mYsql... и какая версия?

У меня Microsoft SQL Server 2000, может это не одно и тоже что и MSSQL? 

Автор: comtat 25.7.2006, 07:28
Цитата(kostas @  24.7.2006,  20:14 Найти цитируемый пост)
база данных точно mSsql ? может вы путаете с mYsql

kostas, под MySQL эти функции работают  smile  

Автор: sgentstuff 25.7.2006, 12:36
У меня Microsoft SQL Server 2000, может это не одно и тоже что и MSSQL?
Ответьте на этот вопрос... 

Автор: kostas 25.7.2006, 15:59
Цитата(comtat @  25.7.2006,  07:28 Найти цитируемый пост)
kostas, под MySQL эти функции работают    

хм smile просто под мусклом не пользовался ими, просто слышал о них, но в конечном итоге написал свои в делфях ))

Цитата(sgentstuff @  25.7.2006,  12:36 Найти цитируемый пост)
У меня Microsoft SQL Server 2000, может это не одно и тоже что и MSSQL?Ответьте на этот вопрос... 

под MSSQL подразумевают в общем Microsoft SQL Server, поэтому в данной ситуации можно сказать что это одно и то же ;) 

Автор: sgentstuff 26.7.2006, 05:38
Цитата(sgentstuff @ 24.7.2006,  12:59)
вот такую ошибку пишет
'INET_NTOA' is not a recognized function name.

Так почему он не может найти эту функцию? 

Автор: sgentstuff 26.7.2006, 06:52
под MSSQL подразумевают в общем Microsoft SQL Server, поэтому в данной ситуации можно сказать что это одно и то же ;) 
А вобще есть такая СУБД кот. называется MSSQL,  но она не тоже самое что Microsoft SQL? 

Автор: sgentstuff 26.7.2006, 09:43
Цитата(kostas @ 24.7.2006,  11:33)
В MSSQL есть встроенные фукнции для конвертации длинного формата IP в короткий integer и наоборот - INET_ATON и INET_NTOA. Таким образом можно будет вытащить IP адреса из необходимого диапазона. Вообще я бы хранил изначально именно в числовом формате, т.к. и места требует меньше и работать удобней.

Искал. Скорее всего в MSSQL таких функций нет. 

Автор: kobra 26.7.2006, 10:28
Цитата(sgentstuff @  26.7.2006,  09:43 Найти цитируемый пост)
Искал. Скорее всего в MSSQL таких функций нет. 
эти функции не из MSSQL.
мне кажется что нужно написать функцию, каторая будет приводить запис к формату ххх.ххх.ххх.ххх. соответственно условие филтра тоже нада также форматировать.  
 

Автор: Vit 27.7.2006, 17:01
Вот реализация конвертации строки с адресом в число:

Код

Create Function dbo.IP_to_Int (@IP varchar(16))
Returns bigint
begin
/*Copyright (c) Vit, 2006*/
Declare @temp1 varchar(3), @Result bigint, @i int

Set @i=patindex('%.%', @IP)
Set @temp1=substring(@IP, 1, @i)
Set @Result=cast(@temp1 as bigint)*256*256*256
Set @IP=substring(@IP, @i+1, 100)

Set @i=patindex('%.%', @IP)
Set @temp1=substring(@IP, 1, @i)
Set @Result=@Result+cast(@temp1 as bigint)*256*256
Set @IP=substring(@IP, @i+1, 100)

Set @i=patindex('%.%', @IP)
Set @temp1=substring(@IP, 1, @i)
Set @Result=@Result+cast(@temp1 as bigint)*256
Set @IP=substring(@IP, @i+1, 100)

Set @Result=@Result+cast(@IP as bigint)

  Return @Result
end


Этим кодом надо создать функцию а потом можно использовать типа такого:
Код


Select * From MyTable 
Where dbo.IP_to_Int (MyAddressField) between dbo.IP_to_Int ('255.255.255.2') and dbo.IP_to_Int ('255.255.255.6')

  

Автор: sgentstuff 28.7.2006, 08:03
Vit cпасибо, вот попроще 

Код

CREATE FUNCTION ip_tobigint  
(
   @ip varchar(15) 
)
RETURNS bigint
AS
BEGIN
RETURN
(
   CAST(PARSENAME(@ip, 4) as bigint) * 16777216 +
   CAST(PARSENAME(@ip, 3) as bigint) * 65536 +
   CAST(PARSENAME(@ip, 2) as bigint) * 256 +
   CAST(PARSENAME(@ip, 1) as bigint)
)
END
GO
 

Автор: Vit 28.7.2006, 21:36
sgentstuff, Круто! Я не додумался использовать PARSENAME таким нетрадиционным способом! Класс! Восхрищён!  

Автор: kostas 29.7.2006, 08:50
Ну вот и решение вопроса smile Я почему то был уверен что эти функции уже есть в mssql...
PS. Кстати если кому нужна их реализация в делфи, могу поделится ;) 

Автор: sgentstuff 1.8.2006, 08:30
kostas - если не трудно выложи в реализацию в делфях, думаю мне и много кому пригодится.

Автор: kostas 1.8.2006, 20:15
Код

function GiveIP(a: integer): string;
begin
  result:=IntToStr(a shr 24)+'.'+IntToStr((A and $00ff0000) shr 16)+'.'+IntToStr((A and $0000FF00) shr 8)+'.'+IntToStr(A and $000000FF);
end;

function GetIP(a: string): Integer;
Var tt:TStringList;
    i: integer;
begin
  if a='' then
   begin
    Result:=0;
    exit;
   end;
  tt:=TStringList.Create;
  try
   tt.text:=stringReplace(a,'.',#13#10,[rfReplaceAll]);

   i:=0;
   for i:=4 downto 1 do
    Result:=(Result shl 8) or (StrToInt(tt[4-i]));
  finally
   tt.Free;
  end;
end;

Между прочим в делфи где то есть эти функции, по крайней мере в семерке, но когда писал эти о тех еще не знал  smile 

Автор: sgentstuff 2.8.2006, 13:06
Туда.
Код

CREATE FUNCTION ip_tobigint  
(
   @ip varchar(15) 
)
RETURNS bigint
AS
BEGIN
RETURN
(
   CAST(PARSENAME(@ip, 4) as bigint) * 16777216 +
   CAST(PARSENAME(@ip, 3) as bigint) * 65536 +
   CAST(PARSENAME(@ip, 2) as bigint) * 256 +
   CAST(PARSENAME(@ip, 1) as bigint
)
END
GO


Обратно.
Код

CREATE FUNCTION dbo.bigint_toip
(
   @bigint bigint
)
RETURNS varchar(15)
AS
BEGIN
RETURN
(
selectconvert(varchar, convert(int, substring(ip, 5, 1))) + '.' +
convert(varchar, convert(int, substring(ip, 6, 1))) + '.' +
convert(varchar, convert(int, substring(ip, 7, 1))) + '.' +
convert(varchar, convert(int, substring(ip, 8, 1)))
from (
select convert(varbinary(8), @bigint) as ip
) as i
)
END


Автор: Демо 5.8.2006, 01:09
Цитата(sgentstuff @  1.8.2006,  08:30 Найти цитируемый пост)
если не трудно выложи в реализацию в делфях, думаю мне и много кому пригодится.


Реализация в сетях есть:

Код

type

  SunB = packed record
    s_b1, s_b2, s_b3, s_b4: Char;
  end;

  SunW = packed record
    s_w1, s_w2: word;
  end;

  TInAddr = record
    case integer of
      0: (S_un_b: SunB);
      1: (S_un_w: SunW);
      2: (S_addr: LongInt);
  end;

  function inet_addr(cp: PChar): LongInt; stdcall; external 'wsock32.dll' name 'inet_addr';
  function inet_ntoa(inaddr: TInAddr): PChar; stdcall; external 'wsock32.dll' name 'inet_ntoa';
  function htonl(hostlong: LongInt): LongInt; stdcall; external 'wsock32.dll' name 'htonl';
  function ntohl(netlong: LongInt): LongInt; stdcall; external 'wsock32.dll' name 'ntohl';

function IP2D(ip: String): LongInt;
begin
    Result := inet_addr(PChar(ip));
end;

function D2IP(ip: LongInt):String;
var
    p: PChar;
    d: TInAddr;
begin
  d.S_addr := ip;
  p := inet_ntoa(d);
  Result := p;
end;

function IncIp(ip: String; IncValue: Integer=1):String;
var
    d: TInAddr;
begin
  d.S_addr := ntohl(htonl(IP2D(ip))+IncValue);
  Result := String(inet_ntoa(d));
end;

function DecIp(ip: String; DecValue: Integer=1):String;
var
    d: TInAddr;
begin
  d.S_addr := ntohl(htonl(IP2D(ip))-DecValue);
  Result := String(inet_ntoa(d));
end;

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)