También es posible usar un objeto de Oracle personalizado.
SQL>set SERVEROUTPUT on
SQL>drop table test;
Table dropped.
SQL>drop type body inaddr;
Type body dropped.
SQL>drop type inaddr;
Type dropped.
SQL>create type inaddr as object
2 (/* TODO enter attribute and method declarations here */
3 A number(5),
4 B number(5),
5 C number(5),
6 D number(5),
7 E number(5),
8 F number(5),
9 G number(5),
10 H NUMBER(5),
11 MAP MEMBER FUNCTION display RETURN VARCHAR2,
12 MEMBER FUNCTION toString(SELF IN INADDR , CONTRACT BOOLEAN DEFAULT TRUE) RETURN VARCHAR2,
13 CONSTRUCTOR FUNCTION INADDR(SELF IN OUT NOCOPY INADDR, INADDRASSTRING VARCHAR2) RETURN SELF AS RESULT
14
15 ) NOT FINAL;
16/
SP2-0816: Type created with compilation warnings
SQL>
SQL>
SQL>CREATE TYPE BODY INADDR AS
2
3 MAP MEMBER FUNCTION display RETURN VARCHAR2
4 IS BEGIN
5 return tostring(FALSE);
6 END;
7
8
9 MEMBER FUNCTION TOSTRING(SELF IN INADDR , CONTRACT BOOLEAN DEFAULT TRUE) RETURN VARCHAR2 IS
10 IP4 VARCHAR2(6) := 'FM990';
11 ip6 varchar2(6) := 'FM0XXX';
12 BEGIN
13 IF CONTRACT THEN
14 ip6 := 'FMXXXX';
15 end if;
16
17 IF CONTRACT AND A =0 AND B=0 AND C = 0 AND D=0 AND E =0 AND F = 65535 THEN --ipv4
18 RETURN '::FFFF:'||TO_CHAR(TRUNC(G/256),'FM990.')||TO_CHAR(MOD(G,256),'FM990.')||TO_CHAR(TRUNC(H/256),'FM990.')||TO_CHAR(MOD(H,256),'FM990');
19 ELSE
20 RETURN
21 TO_CHAR(A,ip6)||':'||
22 TO_CHAR(B,IP6)||':'||
23 TO_CHAR(C,ip6)||':'||
24 TO_CHAR(D,ip6)||':'||
25 TO_CHAR(E,ip6)||':'||
26 TO_CHAR(F,ip6)||':'||
27 TO_CHAR(G,ip6)||':'||
28 TO_CHAR(H,ip6);
29 end if;
30 end;
31
32 CONSTRUCTOR FUNCTION inaddr(SELF IN OUT NOCOPY inaddr, inaddrasstring VARCHAR2)
33 RETURN SELF AS RESULT IS
34 begin
35 if instr(inaddrasstring,'.') > 0 then
36 --ip4
37 null;
38 a := 0;
39 B := 0;
40 C := 0;
41 D := 0;
42 E := 0;
43 F := TO_NUMBER('FFFF', 'XXXX');
44 G := TO_NUMBER(TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,1,'i',1),'999'),'FM0X')
45 ||TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,2,'i',1),'999'),'FM0X')
46 ,'XXXX');
47 h := TO_NUMBER(TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3}).',1,3,'i',1),'999'),'FM0X')
48 ||TO_CHAR(TO_NUMBER(REGEXP_SUBSTR(INADDRASSTRING,'([0-9]{1,3})',1,4,'i',1),'999'),'FM0X')
49 ,'XXXX');
50
51 ELSIF instr(inaddrasstring,':') > 0 then
52 --ip6
53 a := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,1,'i',1),'XXXX');
54 b := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,2,'i',1),'XXXX');
55 c := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,3,'i',1),'XXXX');
56 d := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,4,'i',1),'XXXX');
57 E := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,5,'i',1),'XXXX');
58 f := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,6,'i',1),'XXXX');
59 g := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,7,'i',1),'XXXX');
60 H := TO_NUMBER(REGEXP_SUBSTR(inaddrasstring,'([0-9a-fA-F]{1,4})',1,8,'i',1),'XXXX');
61 end if;
62
63 RETURN;
64 END;
65 end;
66/
Type body created.
SQL>
SQL>create table test
2 (id integer primary key,
3 address inaddr);
Table created.
SQL>
SQL>select * from test;
no rows selected
SQL>
SQL>
SQL>insert into test values (1, INADDR('fe80:0000:0000:0000:0202:b3ff:fe1e:8329'));
1 row created.
SQL>INSERT INTO TEST VALUES (2, INADDR('192.0.2.128'));
1 row created.
SQL>insert into test values (3, INADDR('20.0.20.1'));
1 row created.
SQL>insert into test values (4, INADDR('fe80:0001:0002:0003:0202:b3ff:fe1e:8329'));
1 row created.
SQL>insert into test values (5, INADDR('fe80:0003:0002:0003:0202:b3ff:fe1e:8329'));
1 row created.
SQL>INSERT INTO TEST VALUES (6, INADDR('fe80:0003:0001:0003:0202:b3ff:fe1e:8329'));
1 row created.
SQL>INSERT INTO TEST VALUES (7, INADDR('fe80:0003:0001:0003:0202:b3ff:fe1e:8328'));
1 row created.
SQL>INSERT INTO TEST VALUES (8, INADDR('dead:beef:f00d:cafe:dea1:aced:b00b:1234'));
1 row created.
SQL>
SQL>COLUMN INET_ADDRESS_SHORT FORMAT A40
SQL>column inet_address_full format a40
SQL>
SQL>select t.address.toString() inet_address_short, t.address.display() inet_address_full
2 from test T
3 order by t.address ;
INET_ADDRESS_SHORT INET_ADDRESS_FULL
---------------------------------------- ----------------------------------------
::FFFF:20.0.20.1 0000:0000:0000:0000:0000:FFFF:1400:1401
::FFFF:192.0.2.128 0000:0000:0000:0000:0000:FFFF:C000:0280
DEAD:BEEF:F00D:CAFE:DEA1:ACED:B00B:1234 DEAD:BEEF:F00D:CAFE:DEA1:ACED:B00B:1234
FE80:0:0:0:202:B3FF:FE1E:8329 FE80:0000:0000:0000:0202:B3FF:FE1E:8329
FE80:1:2:3:202:B3FF:FE1E:8329 FE80:0001:0002:0003:0202:B3FF:FE1E:8329
FE80:3:1:3:202:B3FF:FE1E:8328 FE80:0003:0001:0003:0202:B3FF:FE1E:8328
FE80:3:1:3:202:B3FF:FE1E:8329 FE80:0003:0001:0003:0202:B3FF:FE1E:8329
FE80:3:2:3:202:B3FF:FE1E:8329 FE80:0003:0002:0003:0202:B3FF:FE1E:8329
8 rows selected.
SQL>spool off
acabo de poner esto juntos en la última hora (y enseñó a mí mismo objetos al mismo tiempo) así que estoy seguro de que puede ser mejorado.si hago cambios voy a repost aquí
¿Hace agregaciones/búsqueda en esa tabla por dirección IP? ¿Cuántas filas espera tener en 1 año? – jachguate
Agregaciones y búsqueda por IP, sí. Número de filas, posiblemente cientos de millones. (¿Tiene recomendaciones pequeñas/medianas/grandes?) – pilcrow
por favor, use la notación @jachguate en sus comentarios si quiere que me notifiquen al respecto. Por lo que dices, creo que el mejor enfoque es el primero de la respuesta de @Alain. – jachguate