Oracleデータベース内の階層テキストを検索する

表= BLOCK(複合ユニーク索引と両方の列を持つ)

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

要件:

  • サブブロックは許可されていません。例えば、これは67.7の子供であるため、67.7.1と24は許可されていません。つまり、新しい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の倍数で重ならないなら、Instrは機能しません。 10.224/11 は 10.240/12 の親ですが、 10.176/12
追加された 著者 Sodved,
ありがとう。私はip_addressをバイナリビットフォーマットとして保持しているテーブルに別のカラムを追加しても構いません。これはLIKE句の反対のクエリを使ってこれを達成するのに役立ちます。
追加された 著者 Sannu,