我有下表
Table bots{
ip_address varchar(15),
bot_name varchar(32)
}
鉴于某些机器人具有静态ips而其他机器人不具有静态ips,该表具有诸如192.168.0和192.168.1.15之类的条目
现在我必须看看给定的ip是否属于机器人。我正在思考这些问题
SELECT bot_name
FROM bots
WHERE __input_ip__ REGEXP '^ip_address'
但这不会起作用,因为它正在寻找以ip_address开头的字符串。
所以我的问题是,如何在sql正则表达式中包含字段名称?
答案 0 :(得分:4)
您可能需要考虑将IP地址存储为INT UNSIGNED。还要存储网络掩码,以便区分静态地址和子网。
INSERT INTO bots (ipaddress, netmask, bot_name)
VALUES (INET_ATOI('192.168.1.0'), INET_ATOI('255.255.255.0'), 'Wall-E');
然后您可以查询输入IP地址是否匹配:
SELECT bot_name
FROM bots
WHERE __input_ip__ & netmask = ipaddress & netmask;
对IP地址而不是CHAR(15)使用整数是一种常见的优化。即使存储IP地址和网络掩码的8个字节也只是CHAR(15)存储量的一半。并且按位运算可能比正则表达式匹配快得多,并且更容易避免像@Gumbo评论中的极端情况。
答案 1 :(得分:2)
试试这个:
SELECT bot_name
FROM bots
WHERE __input_ip__ REGEXP concat('^', replace(ip_address, '.', '\.'))
答案 2 :(得分:1)
(这是对安德鲁答案的回应,但不适合评论。)
WHERE __input_ip__ REGEXP concat('^', replace(ip_address, '.', '\.'))
好的计划,除了在MySQL \中是一个(非标准的SQL)字符串文字转义,所以要在regexp中得到一个,你可能需要'\\\.'
!
...除了在ANSI模式下它不会。哎呀!为了兼容,你必须以另一种方式获得反斜杠:
WHERE __input_ip__ REGEXP CONCAT('^', REPLACE(ip_address, '.', CHAR(92, 46)))
唉。也许最好忘记正则表达式并使用字符串操作:
WHERE LEFT(__input_ip__, CHAR_LENGTH(ip_address))=__input_ip__