Поиск иерархического текста в базе данных Oracle

Таблица = БЛОК (имеет составной уникальный индекс как для столбцов)

IP_ADDRESS   CIDR_SIZE
=========    ==========
10.10         16
15.0          16
67.7          16
18.0           8

Требования:

  • Подблочный блок не разрешен. Напр. 67.7.1 и 24 не разрешены, так как это ребенок 67.7. Другими словами, если в базе данных есть какой-либо IP-адрес, соответствующий начальной части нового IP-адреса, то он должен завершиться неудачей. Возможно ли это сделать с помощью SQL-запроса Oracle?

Я думал об этом ...

  1. Select all records into the memory.
  2. Convert each IP into its binary bits

    10.10 = 00001010.00001010
    15.0 = 00001111.00000000
    67.7 = 01000011.00000111
    18.0 = 00010010.00000000

  3. Convert new IP into binary bit. 67.7.1 = 01000011.00000111.00000001

  4. Check to see if new IP binary bits start with existing IP binary bits.
  5. If true, then the new record exists in the database. For example, new binary bit 01000011.00000111.00000001 does start with existing ip (67.7) binary bits 01000011.00000111. Rest of records don't match.

Я смотрю, есть ли запрос Oracle, который может сделать это для меня, то есть вернуть соответствующие IP-адреса из базы данных. Я проверил текстовый API Oracle, но пока ничего не нашел.

0

2 ответы

Да, вы можете сделать это в SQL, преобразовывая IP-адреса в числа, а затем убедитесь, что это не запись с меньшим размером cidr , который дает тот же ipnum при использовании его размера cidr .

WITH ipv AS
(   SELECT  IP.*
        ,   NVL(REGEXP_SUBSTR( ip, '\d+', 1, 1 ),0) * 256 * 256 * 256  -- octet1
        +   NVL(REGEXP_SUBSTR( ip, '\d+', 1, 2 ),0) * 256 * 256        -- octet2
        +   NVL(REGEXP_SUBSTR( ip, '\d+', 1, 3 ),0) * 256              -- octet3
        +   NVL(REGEXP_SUBSTR( ip, '\d+', 1, 4 ),0)  AS ipnum          -- octet4
        ,   32-bits                 AS ignorebits
    FROM  ips IP
)
SELECT  IP1.ip, IP1.bits
FROM    ipv IP1
WHERE   NOT EXISTS
    (   SELECT  1
        FROM    ipv IP2
        WHERE   IP2.bits < IP1.bits
        AND     TRUNC( IP2.ipnum/POWER( 2, IP2.ignorebits ) )
              = TRUNC( IP1.ipnum/POWER( 2, IP2.ignorebits ) )
    )

Примечание. В моем примере используется таблица, эквивалентная вашей:

SQL> desc ips
 Name                                      Null?    Type
 ----------------------------------------- -------- ----------------------------
 IP                                        NOT NULL VARCHAR2(16)
 BITS                                      NOT NULL NUMBER
0
добавлено

Is there a reason you can't use the INSTR function? http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/functions068.htm#i77598

I'd do something like a NOT EXISTS clause that checks for INSTR(b_outer.IP_ADDRESS,b_inner.IP_ADDRESS) <> 1

* edit: подумав об этом, вам, вероятно, нужно будет проверить, соответствует ли результат 1 (что означает, что потенциальный IP-адрес соответствует началу первого символа существующего IP-адреса), в отличие от обычного поиска подстроки, поскольку я изначально имел это ,

0
добавлено
Instr не работает, если количество бит не перекрывается с коэффициентом 8, например. 10.224/11 является родителем 10.240/12 Но не 10.176/12
добавлено автор Sodved, источник
Благодарю. Я не возражаю добавить еще один столбец в таблицу, который сохраняет ip_address в виде бинарного битового формата, если это поможет мне достичь этого, используя только запрос, возможно, нечто противоположное предложению LIKE.
добавлено автор Sannu, источник
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Oracle RU
Oracle RU
303 участник(ов)

Русскоязычная группа по Oracle. — Архитектура СУБД — PL/SQL — Оптимизация — Администрирование — Вакансии Oracle (указать инфу по вилке ЗП и удалёнке) Приглашайте коллег :-) Запрещены: личные оскорбления, обсуждения оффтопик вопросов политики и религии

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async