mysql数据库中,插入一个范围的ip,判断已有数据中是否包含该ip的任意值

qq_charm 2018-05-29 09:38:10
正在做一个java的ip后台管理系统。需求就是在插入ip范围的时候判断mysql数据库中是否存在该范围的任意值(任意一个Ip),如果有就不能插入,没有就插入。

目前表结构是beginIP 和endIP 表中数据是字符串格式.如192.168.1.50(beginIP)----192.168.70(endIP)。这样的ip段有很多,现在我想插入一个ip范围。比如192.168.1.40(beginIP)-----192.168.1.60(endIP)。在插入的时候需要进行判断我插入的这个范围里面是否有任意一个ip在已有的ip范围内,如果有就不能插入,没有才插入。还有,如果插入的是比如192.168.1.1----192.168.1.255这种范围包含了数据库中已有的范围也是不行的。这样的逻辑应该怎么实现?改表结构都可以
...全文
981 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
qq_charm 2018-05-31
  • 打赏
  • 举报
回复
引用 6 楼 crynono 的回复:
drop PROCEDURE if EXISTS addIP; create PROCEDURE addIP(in ip1 varchar(20),in ip2 varchar(20)) MODIFIES sql DATA Home: BEGIN declare sip1,sip2 bigint; declare minbip,maxeip bigint; declare intbip,inteip bigint; DECLARE done INT DEFAULT FALSE; declare cur1 cursor for select INET_ATON(beginIP),INET_ATON(endIP) from iptable; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; set sip1=INET_ATON(ip1); set sip2=INET_ATON(ip2); if(sip1>sip2) then leave Home; end if; select INET_ATON(min(beginIP)),INET_ATON(max(endIP)) into minbip,maxeip from iptable; OPEN cur1; read_loop: LOOP FETCH cur1 INTO intbip, inteip; IF done THEN LEAVE read_loop; END IF; IF(sip1>=intbip && sip1<=inteip) THEN leave Home; END IF; IF(sip2>=intbip && sip2<=inteip) THEN leave Home; end if; IF(sip1<minbip && sip2>maxeip) THEN leave Home; end if; END LOOP; CLOSE cur1; insert into iptable VALUES(null,ip1,ip2); end 这样就可以了
完美
crynono 2018-05-31
  • 打赏
  • 举报
回复
drop PROCEDURE if EXISTS addIP; create PROCEDURE addIP(in ip1 varchar(20),in ip2 varchar(20)) MODIFIES sql DATA Home: BEGIN declare sip1,sip2 bigint; declare minbip,maxeip bigint; declare intbip,inteip bigint; DECLARE done INT DEFAULT FALSE; declare cur1 cursor for select INET_ATON(beginIP),INET_ATON(endIP) from iptable; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; set sip1=INET_ATON(ip1); set sip2=INET_ATON(ip2); if(sip1>sip2) then leave Home; end if; select INET_ATON(min(beginIP)),INET_ATON(max(endIP)) into minbip,maxeip from iptable; OPEN cur1; read_loop: LOOP FETCH cur1 INTO intbip, inteip; IF done THEN LEAVE read_loop; END IF; IF(sip1>=intbip && sip1<=inteip) THEN leave Home; END IF; IF(sip2>=intbip && sip2<=inteip) THEN leave Home; end if; IF(sip1<minbip && sip2>maxeip) THEN leave Home; end if; END LOOP; CLOSE cur1; insert into iptable VALUES(null,ip1,ip2); end 这样就可以了
qq_charm 2018-05-31
  • 打赏
  • 举报
回复
引用 3 楼 crynono 的回复:
1、假设有这样一个表,定义如下 create table iptable (uid int auto_increment primary key, beginIP varchar(20), endIP varchar(20) ); 2、添加一行数据,范围是50-70 insert into iptable values(null,'192.168.1.50','192.168.1.70'); 3、创建一个用来插入IP范围的存储过程(需要2个参数,ip1是起始IP,ip2是终止IP),存储过程如下 drop PROCEDURE if EXISTS addIP; create PROCEDURE addIP(in ip1 varchar(20),in ip2 varchar(20)) MODIFIES sql DATA Home: BEGIN declare sip1,sip2 bigint; declare intbip,inteip bigint; DECLARE done INT DEFAULT FALSE; declare cur1 cursor for select INET_ATON(beginIP),INET_ATON(endIP) from iptable; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; set sip1=INET_ATON(ip1); set sip2=INET_ATON(ip2); if(sip1>sip2) then leave Home; end if; OPEN cur1; read_loop: LOOP FETCH cur1 INTO intbip, inteip; IF done THEN LEAVE read_loop; END IF; IF(sip1>=intbip && sip1<=inteip) THEN leave Home; END IF; IF(sip2>=intbip && sip2<=inteip) THEN leave Home; end if; END LOOP; CLOSE cur1; insert into iptable VALUES(null,ip1,ip2); end 4、测试 call addIP('192.168.1.35','192.168.1.45'); 成功插入35-45这个范围 call addIP('192.168.1.50','192.168.1.60'); 插入失败,因为已存在50-70这个范围
这个确实是可以,但是你还有个逻辑就是 如果我插入的这个范围,包含了已有的范围就不能插入,这个怎么解决?
crynono 2018-05-30
  • 打赏
  • 举报
回复
上面的逻辑漏掉了192.168.1.1----192.168.1.255这种范围。。。 但按理说这个逻辑应该由你的java程序来处理,而不是数据库
crynono 2018-05-30
  • 打赏
  • 举报
回复
1、假设有这样一个表,定义如下 create table iptable (uid int auto_increment primary key, beginIP varchar(20), endIP varchar(20) ); 2、添加一行数据,范围是50-70 insert into iptable values(null,'192.168.1.50','192.168.1.70'); 3、创建一个用来插入IP范围的存储过程(需要2个参数,ip1是起始IP,ip2是终止IP),存储过程如下 drop PROCEDURE if EXISTS addIP; create PROCEDURE addIP(in ip1 varchar(20),in ip2 varchar(20)) MODIFIES sql DATA Home: BEGIN declare sip1,sip2 bigint; declare intbip,inteip bigint; DECLARE done INT DEFAULT FALSE; declare cur1 cursor for select INET_ATON(beginIP),INET_ATON(endIP) from iptable; DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = TRUE; set sip1=INET_ATON(ip1); set sip2=INET_ATON(ip2); if(sip1>sip2) then leave Home; end if; OPEN cur1; read_loop: LOOP FETCH cur1 INTO intbip, inteip; IF done THEN LEAVE read_loop; END IF; IF(sip1>=intbip && sip1<=inteip) THEN leave Home; END IF; IF(sip2>=intbip && sip2<=inteip) THEN leave Home; end if; END LOOP; CLOSE cur1; insert into iptable VALUES(null,ip1,ip2); end 4、测试 call addIP('192.168.1.35','192.168.1.45'); 成功插入35-45这个范围 call addIP('192.168.1.50','192.168.1.60'); 插入失败,因为已存在50-70这个范围
qq_charm 2018-05-30
  • 打赏
  • 举报
回复
引用 1 楼 crynono 的回复:
32位二进制的ip地址是可以转换为对应的整数的。所以拿整数来比较可能比较方便。逻辑上比较简单, 写个存储过程来实现, 定义个游标来循环遍历每一个已有范围 分别拿即将插入的beginip、endip 和每一个已有范围来比较一下,一旦beginip或者endip介于哪一个已有范围内, 说明不应该插入,终止循环。 循环结束后仍没有匹配上,则插入。
这样好像可以的,大神呢个不能给个代码,这个存储过程不太会写啊
crynono 2018-05-30
  • 打赏
  • 举报
回复
32位二进制的ip地址是可以转换为对应的整数的。所以拿整数来比较可能比较方便。逻辑上比较简单, 写个存储过程来实现, 定义个游标来循环遍历每一个已有范围 分别拿即将插入的beginip、endip 和每一个已有范围来比较一下,一旦beginip或者endip介于哪一个已有范围内, 说明不应该插入,终止循环。 循环结束后仍没有匹配上,则插入。

56,687

社区成员

发帖
与我相关
我的任务
社区描述
MySQL相关内容讨论专区
社区管理员
  • MySQL
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧