Oracle дерекқорында иерархиялық мәтінді іздеу

Кесте = BLOCK (құрамдас бірегей индексі бағандар сияқты)

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

Талаптар:

  • Ішкі блокқа рұқсат етілмейді. Мысалы, мысалы: 67.7.1 және 24-ке жол берілмейді, себебі бұл 67.7-ке дейінгі бала. Басқаша айтқанда, дерекқорда жаңа IP-нің басталатын бөлігіне сәйкес келетін кез-келген IP-адресі болса, ол сәтсіздікке ұшырауы керек. Мен мұны Oracle SQL сұрауы арқылы жасай аламын ба?

Мен оны мұны істеуді ойладым ...

  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 мекенжайларын дерекқордан қайтарады. Мен Oracle Text API-ні тексердім, бірақ әлі ештеңе таппадым.

0

2 жауаптар

Ияны 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

* Өңдеу: бұл туралы ойлап, нәтиже 1-ді (әлеуетті IP-адресті бар IP-мекен-жайдың бірінші таңбасынан басталатындығын білдіреді) жалпы субстринді іздеуден айырмашылығын тексеруге тура келеді .

0
қосылды
Егер биттердің саны 8-ға тең болмаса, онда жұмыс істемейді. 10.224/11 - 10.240/12
қосылды автор Sodved, көзі
Рахмет. Ip_address екілік бит пішімі ретінде сақтайтын кестеге басқа баған қосуға қарсы емеспін, егер бұл маған тек LIKE тармағына қарама-қайшы келетін нәрсе арқылы ғана қол жеткізуге көмектесетін болса.
қосылды автор Sannu, көзі