@ RobVanWijk делает соответствующий комментарий:
Вы можете утверждать, что это должно быть
хранится вместо четырех числовых столбцов
из 1 строки.
Это классический случай, когда было бы здорово, если бы мы могли определять домены данных в наших схемах. Oracle не поддерживает это, но, если честно, ни один из других поставщиков СУБД. Тем не менее, мы можем использовать пользовательские типы для создания сложных типов данных с прикрепленным поведением. Обидно, что синтаксис UDT такой неуклюжий.
Как бы то ни было, комментарий Роба напомнил мне, что я недавно создал Proof of Concept, используя этот домен. Я публикую это не как серьезное решение, а как показатель того, насколько аккуратными могут быть вещи ...
Спецификация типа ...
create or replace type ip_address_t as object
(octet1 number(3,0)
, octet2 number(3,0)
, octet3 number(3,0)
, octet4 number(3,0)
, constructor function ip_address_t
(octet1 number, octet2 number, octet3 number, octet4 number)
return self as result
, member function to_string
return varchar2
, member function to_padded_string
return varchar2
, map member function sort_order return number)
/
... и тело ...
create or replace type body ip_address_t as
constructor function ip_address_t
(octet1 number, octet2 number, octet3 number, octet4 number)
return self as result
is
begin
if ( octet1 is null or octet2 is null or octet3 is null or octet4 is null )
then
raise INVALID_NUMBER;
else
self.octet1 := octet1;
self.octet2 := octet2;
self.octet3 := octet3;
self.octet4 := octet4;
end if;
return;
end ip_address_t;
member function to_string return varchar2
is
begin
return trim(to_char(self.octet1))||'.'||
trim(to_char(self.octet2))||'.'||
trim(to_char(self.octet3))||'.'||
trim(to_char(self.octet4));
end to_string;
member function to_padded_string return varchar2
is
begin
return lpad(trim(to_char(self.octet1)),3,'0')||'.'||
lpad(trim(to_char(self.octet2)),3,'0')||'.'||
lpad(trim(to_char(self.octet3)),3,'0')||'.'||
lpad(trim(to_char(self.octet4)),3,'0');
end to_padded_string;
map member function sort_order return number
is
begin
return to_number(
lpad(trim(to_char(self.octet1)),3,'0')||
lpad(trim(to_char(self.octet2)),3,'0')||
lpad(trim(to_char(self.octet3)),3,'0')||
lpad(trim(to_char(self.octet4)),3,'0')
);
end sort_order;
end;
/
Я буду использовать этот тип для определения столбца в тестовой таблице, который я буду заполнять некоторыми тестовыми данными.
SQL> create table t23 (id number, domnain_name varchar2(128), ip_address ip_address_t)
2 /
Table created.
SQL> insert into t23 values (1000, 'http://www.example.com', ip_address_t(8,1,3,0))
2 /
1 row created.
SQL> insert into t23 values (800, 'http://www.example1.com', ip_address_t(9,1,2,0))
2 /
1 row created.
SQL> insert into t23 values (1100, 'http://www.example2.com', ip_address_t(10,1,2,0))
2 /
1 row created.
SQL> insert into t23 values (1103, 'http://www.example3.com', ip_address_t(10,1,25,0))
2 /
1 row created.
SQL> insert into t23 values (1102, 'http://www.example4.com', ip_address_t(1,11,25,0))
2 /
1 row created.
SQL> insert into t23 values (1101, 'http://www.example5.com', ip_address_t(11,1,25,0))
2 /
1 row created.
SQL>
Всегда помните: при ссылках на атрибуты или методы столбца UDT мы должны использовать псевдоним таблицы :
SQL> select t.id
2 , t.ip_address.to_string() as ip_address
3 from t23 t
4 order by t.ip_address.sort_order()
5 /
ID IP_ADDRESS
---------- ---------------
1102 1.11.25.0
1000 8.1.3.0
800 9.1.2.0
1100 10.1.2.0
1103 10.1.25.0
1101 11.1.25.0
SQL>