7. Dezember 2007

TABLE OF XMLTYPE ... oder "normale" Spalte: Was ist der Unterschied ...?

English title: TABLE OF XMLTYPE ... or "normal" column: What's the difference?

This post is about a "very special" Oracle XML feature: Most people know that there are two ways to create a table for XML documents
Heute geht es wieder mal um das Thema XML und dabei um eine "Spezialität" der objektrelationalen Features in Oracle. Schaut man sich in der Dokumentation um, dann kann man feststellen, dass man eine XML-Tabelle auf zweierlei Art und Weise anlegen kann:
  1. CREATE TABLE XMLTAB1 (xml_document XMLTYPE);
  2. CREATE TABLE XMLTAB2 OF XMLTYPE;
Beyond the fact that the latter variant allows only one column: What's the difference ...?
Mal abgesehen davon, dass man bei der zweiten Variante keine weiteren Spalten mehr angeben kann: Was ist eigentlich der Unterschied ...?
The documentation of the object-relational features states that the first table stores the XML documents as column objects, the second table as row objects. But what are the consequences ...? To find out more we dig into the oracle data dictionary:
Wenn man in die Dokumentation zu den objektrelationalen Features, dann stellt man fest, dass die XML-Dokumente im ersten Fall als Column Objects und im zweiten Fall als Row Objects gespeichert werden. Aber was bedeutet das nun im Detail ...? Dazu sehen wir uns ein wenig im Data Dictionary um:
SQL> select COLUMN_NAME, DATA_TYPE, VIRTUAL_COLUMN, HIDDEN_COLUMN from user_tab_cols where TABLE_NAME='XMLTAB1'

COLUMN_NAME                    DATA_TYPE                      VIR HID
------------------------------ ------------------------------ --- ---
XML_DOCUMENT                   XMLTYPE                        YES NO
SYS_NC00002$                   CLOB                           NO  YES
The table XMLTAB1 ("column objects") contains XML_DOCUMENT as specified in the CREATE TABLE statement. But this is a virtual (derived) column. In addition there is the hidden column SYS_NC00002$ of type CLOB. When there are no storage parameters for XML, Oracle chooses the text-based storage, as explained more detailed in the post XML Speicherungsformen (german). Therefore this hidden column SYS_NC00002$ does actually store the XML text. The column XML_DOKUMENT is just derived (BTW: Here we can see that Virtual Columns in Oracle11g are not really a "new feature": the Oracle database did use them in previous versions; but Oracle11g exposes them externally.)
Die Tabelle XMLTAB1 mit den "Column Objects" enthält die im CREATE TABLE-Kommando angegebene Spalte XML_DOCUMENT als virtuelle, also "abgeleitete" Spalte und zusätzlich die versteckte (Hidden) Spalte SYS_NC00002$ vom Typ CLOB. Wie bereits im Post über die Speicherungsformen geschrieben, wird ein XMLTYPE als CLOB gespeichert, wenn man bei Tabellenerstellung nix anderes angibt. Und diese versteckte Spalte SYS_NC00002$ nimmt das eigentliche XML-Dokument auf. Die sichtbare Spalte XML_DOKUMENT ist dagegen eine daraus abgeleitete virtual Column. (Übrigens: Daran ist erkennbar, dass Virtual Columns in Oracle11g kein wirklich neues Feature ist - es wurde lediglich für den Anwender nutzbar gemacht. Virtuelle Spalten gab's auch schon vorher.)
But what about the table OF XMLTYPE ("row objects")?
Aber wie sieht es nun mit der Tabelle OF XMLTYPE, also den "Row Objects" aus?
SQL> select COLUMN_NAME, DATA_TYPE, VIRTUAL_COLUMN, HIDDEN_COLUMN from user_tab_cols where TABLE_NAME='XMLTAB2'

COLUMN_NAME                    DATA_TYPE                      VIR HID
------------------------------ ------------------------------ --- ---
SYS_NC_OID$                    RAW                            NO  YES
SYS_NC_ROWINFO$                XMLTYPE                        YES NO
XMLDATA                        CLOB                           NO  YES
Again, there is a hidden column (XMLDATA), which contains the actual XML data, and a derived (virtual) column. The virtual column is now named SYS_NC_ROWINFO$, as we did not specify a column name during table creation (CREATE TABLE ... OF XMLTYPE). Compared with the first table there is an additional column: SYS_NC_OID$. This column contains a unique object id for each XML document. This object id allows to create a pointer for each XML document.
Wiederum haben wir eine versteckte Spalte (XMLDATA), welche die eigentlichen XML-Daten aufnimmt und eine abgeleitete (virtuelle) Spalte, die hier SYS_NC_ROWINFO$ heißt (bei Tabellenerstellung haben wir hier ja keinen Spaltennamen angegeben). Soweit ist es wie bei der ersten Tabelle. Neu ist die Spalte SYS_NC_OID$, welche eine eindeutige Object-ID für jedes XML-Dokument enthält. Diese Object ID macht es nun möglich, dass man einen Pointer auf das XML-Dokument erzeugen kann:
SQL> insert into xmltab2 values ('<xml-dokument>Ein Text</xml-dokument>');

1 row created.

SQL> select ref(e) from XMLTAB2 e;

REF(E)
--------------------------------------------------------------------------------------
000028020940B3A963EF38DC29E040A50A86F8248140B3A963EF37DC29E040A50A86F824810141DA550000
This reference pointer can now be used to create an entry for the particular XML document in Oracle XML DB's virtual file system (the XML DB Repository). The following example illustrates this using the FTP access (in most cases this must be configured with the script $ORACLE_HOME/rdbms/admin/catxdbdbca.sql):
Und eine solche Referenz könnte man nun nutzen, um das eingefügte XML-Dokument im virtuellen Dateisystem der XML Datenbank erscheinen zu lassen. Im folgenden sei dies anhand des FTP-Zugriffs (ggfs. einrichten mit dem Skript $ORACLE_HOME/rdbms/admin/catxdbdbca.sql) erklärt:
declare
  v_ref ref xmltype;
  v_res boolean;
begin
  select ref(e) into v_ref from xmltab2 e;
  v_res := dbms_xdb.createresource(
    abspath => '/public/testdatei.xml',  -- Pfad, unter dem die virtuelle Datei erzeugt werden soll
    data    => v_ref,                    -- Pointer auf die Tabellenzeile
    sticky  => true                      -- "Klebrig"; beim Löschen der Tabellenzeile verschwindet
                                         -- auch die virtuelle Datei
  );
end;
/
sho err
  
commit
/
Now we browse the virtual file system with a command line FTP client
Nun schauen wir uns das virtuelle Dateisystem mit FTP an
ftp> open host 2100
Connected to host.mydomain.com.
220- host
Unauthorised use of this FTP server is prohibited and may be subject to civil and criminal prosecution.
220 host FTP Server (Oracle XML DB/Oracle Database) ready.
ftp> user scott tiger
331 pass required for SCOTT
230 SCOTT logged in
ftp> cd /public
250 CWD Command successful
ftp> dir
200 PORT Command successful
150 ASCII Data Connection
-rw-r--r--   2 SCOTT    oracle         0 DEC 12 13:03 testdatei.xml
226 ASCII Transfer Complete
ftp> get testdatei.xml
226 ASCII Transfer Complete
ftp: 37 bytes received in 0,05Seconds 1298,24Kbytes/sec.
After "downloading" the file testdatei.xml can be opened using a normal text editor and it contains the XML text which was inserted in the table. Deleting the file via the FTP DELETE command leads the table row also to be deleted. Changing the XML content with a SQL UPDATE command leads the file content to be updated accordingly.
Access to the virtual filesystem is not only possible with FTP but also with HTTP and WebDAV - so this feature is very feasible for data integration scenarios: The next post will show not only how to create a XML view on top of some relational tables, but also how to expose these virtual XML documents as files in the virtual filesystem - clients can get the data via FTP or HTTP.
Schaut man in die Datei hinein, so findet man den eben in die Tabelle eingefügten XML-Text wieder. Löscht man die Datei via FTP DELETE-Kommando, dann verschwindet sie auch aus der Tabelle. Ändert man die Tabellenzeile, so ist die virtuelle Datei sofort mitgeändert.
Wie man beim Einspielen des o.g. Skripts $ORACLE_HOME/rdbms/admin/catxdbdbca.sql feststellt, steht neben FTP auch HTTP zur Verfügung - und da gelten genau die gleichen Bedingungen.
Dieses Feature lässt sich sehr gut zum Datenaustausch nutzen - beim nächsten Mal werde ich zeigen, wie man es zuammen mit XML-Views auf relationale Tabellen einsetzen kann. Man erzeugt dann nicht nur eine XML-Sicht über die relationalen Tabellen, sondern macht die Daten auch gleich per FTP oder HTTP verfügbar. Aber dies ... später ...

Keine Kommentare:

Beliebte Postings