1. Start
  2. Unternehmen
  3. Blog
  4. 23ai: Flexible Domains

Einleitung

In vergangenen Blogbeiträgen haben wir Ihnen bereits die Domains im allgemeinen sowie die Enumeration Domains als Variante vorgestellt. Damit lässt sich schon eine ganze Menge anfangen, aber es gibt auch kompliziertere Situationen. Nehmen wir als Beispiel eine Postadresse. Je nach Region bzw. Land sind verschiedene Werte erforderlich, z.B. das Bundesstaat in den USA. Weiterhin gibt es verschiedene Definitionen der Postleitzahl was die Länge und Zusammenstellung betrifft. Hier kommt man mit einer der bisher  erklärten Domains nicht so recht weiter. Abhilfe schaffen aber die Flexible Domains. Diese bieten die Möglichkeit, mit einer übergeordneten Domain anhand eines Kriteriums zu entscheiden, welche untergeordnete Domain tatsäch zur Anwendung kommen soll. Für unser Beispiel legt man also eine Domain für jedes Adressformat an und erstellt eine übergeordnete Domain, die die Unterscheidung vornimmt.

Einrichtung

Gehen wir also an die Umsetzung. Zuerst werden drei Domains definiert, einmal für das deutsche Adressformat mit 5-stelliger Postleitzahl, einmal für die USA mit dem Bundesstaat als Pflichtfeld und dem dortigen Format für Postleitzahlen und einmal allgemein für den Rest der Welt.

Beginnen wir mit der Domain für deutsche Adressen.

 

MARCO @ DB23AI:PDB1:>create domain dom_addr_ger  as (
  2    address_line_1  as varchar2(50),
  3    address_line_2  as varchar2(50),
  4    city            as varchar2(50),
  5    postcode        as varchar2(10),
  6    state           as varchar2(30),
  7    country         as varchar2(30)
  8  )
  9  constraint dom_addr_ger_chk check (address_line_1 is not null and
 10                                 city is not null and
 11                                 postcode is not null and
 12*                                length(postcode) = 5);

Domain DOM_ADDR_GER created.

 

Hier sind also Straße (address_line_1), Stadt und Postleitzahl erforderlich und die Postleitzahl muss genau 5 Stellen haben. 

Weiter geht es mit der Domain für die Vereinigten Staaten, die Datenfelder müssen dabei jeweils identisch sein.

 

MARCO @ DB23AI:PDB1:>create domain dom_addr_us  as (
  2    address_line_1  as varchar2(50),
  3    address_line_2  as varchar2(50),
  4    city            as varchar2(50),
  5    postcode        as varchar2(10),
  6    state           as varchar2(30),
  7    country         as varchar2(30)
  8  )
  9  constraint dom_addr_us_chk check (address_line_1 is not null and
 10                                 city is not null and
 11                                 state is not null and
 12                                 postcode is not null and
 13*                                regexp_like(postcode, '[0-9]{5}(-[0-9]{4})?') );

Domain DOM_ADDR_US created.

 

Hier ist nun zusätzlich der Bundesstaat (state) zwingend erforderlich und die Postleitzahl wird auf ein anderes Format geprüft.

Zum Schluss noch die allgemeine Domain für den Rest der Welt.

 

MARCO @ DB23AI:PDB1:>create domain dom_addr_def  as (
  2    address_line_1  as varchar2(50),
  3    address_line_2  as varchar2(50),
  4    city            as varchar2(50),
  5    postcode        as varchar2(10),
  6    state           as varchar2(30),
  7    country         as varchar2(30)
  8  )
  9  constraint dom_addr_def_chk check (address_line_1 is not null and
 10                                 city is not null and
 11*                                postcode is not null);

Domain DOM_ADDR_DEF created.

 

 Hier sind die Prüfungen entsprechend einfach und allgemein gehalten.

Wie bringt man nun diese Domains zusammen? Das erledigt die Flexible Domain, die anhand des Wertes der Spalte "country" entscheidet, welche Sub-Domain angewendet werden soll.

 

MARCO @ DB23AI:PDB1:>create flexible domain dom_address_flex (address_line_1, address_line_2, city, postcode, state, country)
  2  choose domain using (country_code varchar2(5))
  3  from case
  4         when country_code in ('DE','GER') then dom_addr_ger(address_line_1, address_line_2, city, postcode, state, country)
  5         when country_code in ('US','USA') then dom_addr_us(address_line_1, address_line_2, city, postcode, state, country)
  6         else dom_addr_def(address_line_1, address_line_2, city, postcode, state, country)
  7*      end;

Flexible DOMAIN created.

Implementierung

Die Anwendung dieser Flexible Domain ist dann analog zu den bereits vorgestellten Varianten. Es wird eine Tabelle erstellt, die alle Spalten enthält und die Domain referenziert.

 

MARCO @ DB23AI:PDB1:>create table addresses (
  2    id              number,
  3    address_line_1  varchar2(50),
  4    address_line_2  varchar2(50),
  5    city            varchar2(50),
  6    postcode        varchar2(10),
  7    state           varchar2(30),
  8    country         varchar2(30),
  9    country_code    varchar2(5),
 10    domain dom_address_flex(address_line_1, address_line_2, city, postcode, state, country)
 11    using (country_code)
 12* );

Table ADDRESSES created.

 

Zum Test füge ich nun eine deutsche Adresse in die Tabelle ein.

 

MARCO @ DB23AI:PDB1:>insert into addresses (
  2    address_line_1, city, postcode, country_code
  3  ) values (
  4    'Strasse', 'Dresden', '01189', 'DE'
  5* );

1 row inserted.

 

Wie erwartet, wird die Zeile eingefügt, das sie allen Kriterien entspricht. Fügt man die gleiche Adresse aber als amerikanische Adresse ein, passiert folgendes:

 

MARCO @ DB23AI:PDB1:>insert into addresses (
  2    address_line_1, city, postcode, country_code
  3  ) values (
  4    'Strasse', 'Dresden', '01189', 'US'
  5* );

Error starting at line : 1 in command -
insert into addresses (
  address_line_1, city, postcode, country_code
) values (
  'Strasse', 'Dresden', '01189', 'US'
)
Error report -
ORA-11534: check constraint (MARCO.SYS_C008436) involving columns ADDRESS_LINE_1, CITY, POSTCODE, STATE, COUNTRY_CODE due to domain constraint MARCO.SYS_DOMAIN_C0057 of domain MARCO.DOM_ADDRESS_FLEX violated

 

Da nun die Domain zur Prüfung amerikanischer Adressen angewendet wird, fehlt die Angabe des Bundesstaates und somit wird ein Fehler produziert. Gebe ich also zusätzlich "Sachsen" als Bundesstaat an, dann kann auch diese Adresse eingefügt werden.

 

MARCO @ DB23AI:PDB1:>insert into addresses (
  2    address_line_1, city, postcode, state, country_code
  3  ) values (
  4    'Strasse', 'Dresden', '01189', 'Saxony', 'US'
  5* );

1 row inserted.

 

Damit ist sicher, dass tatsächlich die verschiedenen Domains abhängig vom Land (country) ausgewählt und angewendet werden.

Fazit

Diese komplexe Variante, Domains zu kombinieren, stellt ein durchaus mächtiges Werkzeug zur Vereinheitlichung und Zentralisierung von Regeln zur Datenintegrität dar und ergänzt die bereits erklärten Varianten der Domains. 

Kommentare

Keine Kommentare

Kommentar schreiben

* Diese Felder sind erforderlich