Mysql имя поля в регулярном выражении - PullRequest
5 голосов
/ 22 сентября 2009

У меня есть следующая таблица

Table bots{
    ip_address varchar(15),
    bot_name varchar(32)
}

Учитывая, что у некоторых ботов есть статические ips, а у других нет, в таблице есть такие записи, как 192.168.0 и 192.168.1.15

Теперь я должен посмотреть, принадлежит ли данный ip боту. Я думал что-то вроде этого

SELECT bot_name
FROM bots
WHERE __input_ip__  REGEXP '^ip_address'

но это не сработает по той очевидной причине, что он ищет строку, начинающуюся с ip_address.

Итак, мой вопрос: как я могу включить имя поля в регулярное выражение sql?

Ответы [ 3 ]

4 голосов
/ 22 сентября 2009

Возможно, вы захотите сохранить 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) является обычной оптимизацией. Даже хранение 8 байтов для IP-адреса и сетевой маски занимает чуть больше половины хранилища CHAR (15). И побитовые операции, вероятно, будут намного быстрее, чем сопоставление с регулярным выражением, и легче избежать угловых случаев, как в комментарии @ Gumbo.

2 голосов
/ 22 сентября 2009

Попробуйте это:

SELECT bot_name
FROM bots
WHERE __input_ip__  REGEXP concat('^', replace(ip_address, '.', '\.'))
1 голос
/ 22 сентября 2009

(Это ответ на ответ Эндрю, но он не помещается в комментарии.)

WHERE __input_ip__  REGEXP concat('^', replace(ip_address, '.', '\.'))

Хороший план, за исключением того, что в MySQL \ есть (нестандартный SQL) строковый литерал escape, поэтому чтобы получить его в регулярном выражении, вам, вероятно, потребуется '\\\.'!

... кроме как в режиме ANSI, это не так. Argh! Чтобы быть совместимым, вы должны получить обратную косую черту другим способом:

WHERE __input_ip__ REGEXP CONCAT('^', REPLACE(ip_address, '.', CHAR(92, 46)))

Тьфу. Может быть, лучше забыть регулярное выражение и сделать это с помощью строки ops:

WHERE LEFT(__input_ip__, CHAR_LENGTH(ip_address))=__input_ip__
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...