Base Handbuch
Anhang
LibreOffice 7.6
Dieses Dokument unterliegt dem Copyright © 2015. Die Beitragenden sind unten aufgeführt. Sie dürfen dieses Dokument unter den Bedingungen der GNU General Public License (http://www.gnu.org/licenses/gpl.html), Version 3 oder höher, oder der Creative Commons Attribution License (http://creativecommons.org/licenses/by/3.0/), Version 3.0 oder höher, verändern und/oder weitergeben.
Warennamen werden ohne Gewährleistung der freien Verwendbarkeit benutzt.
Fast alle Hardware- und Softwarebezeichnungen und weitere Stichworte und sonstige Angaben, die in diesem Buch verwendet werden, sind als eingetragene Marken geschützt.
Da es nicht möglich ist, in allen Fällen zeitnah zu ermitteln, ob ein Markenschutz besteht, wird das Symbol (R) in diesem Buch nicht verwendet.
Mitwirkende/Autoren
Robert Großkopf |
Jost Lange |
Jochen Schiffers |
Michael Niedermair |
|
|
Rückmeldung (Feedback)
Kommentare oder Vorschläge zu diesem Dokument können Sie in deutscher Sprache an die Adresse discuss@de.libreoffice.org senden.
Vorsicht
Alles, was an eine Mailingliste geschickt wird, inklusive der E-Mail-Adresse und anderer persönlicher Daten, die die E-Mail enthält, wird öffentlich archiviert und kann nicht gelöscht werden. Also, schreiben Sie mit Bedacht!
Datum der Veröffentlichung und Softwareversion
Veröffentlicht am 01.08.2023 . Basierend auf der Version LibreOffice 7.6 .
Änderung der Datenbankverbindung für einen Mehrbenutzerbetrieb |
Funktionserweiterungen und -änderungen in Base im Laufe der LO-Versionen |
Um die Barcode-Druckfunktion nutzen zu können, muss der Font «ean13.ttf» installiert sein. Dieser Font ist frei verfügbar.
EAN13-Barcodes können mittels «ean13.ttf» folgendermaßen erstellt werden:
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
Zahl |
Großbuchstaben, A=0 B=1 usw. |
* |
Kleinbuchstaben, a=0 b=1 usw. |
+ |
Siehe hierzu die Abfrage "Barcode_EAN13_ttf_Bericht" der Beispieldatenbank «Medien_ohne_Makros»
In den Tabellendefinitionen und bei der Änderung von Datentypen in Abfragen mit den Funktionen CONVERT oder CAST werden bei einigen Datentypen Informationen zur Anzahl an Zeichen (a), zur Genauigkeit (g, entspricht der Gesamtzahl an Ziffern) und zu den Dezimalstellen (d) erwartet: CHAR(a), VARCHAR(a), DOUBLE(g), NUMERIC(g,d), DECIMAL(g,d) und TIMESTAMP(g).
Hsqldb: TIMESTAMP(g) kann nur die Werte '0' oder '6' annehmen. Die Genauigkeit des Timestamps kann nur direkt über den SQL-Befehl eingegeben werden. Sollen also Zeitangaben im Sportbereich eingetragen werden, so ist TIMESTAMP(6) über Extras → SQL voreinzustellen.
Bei der Migration von Hsqldb nach Firebird wird aus dem Feld für ein Bild ein Datentyp Bild [BLOB] erstellt. Dieser Datentyp arbeitet leider nicht korrekt mit dem Grafischen Kontrollfeld zusammen, so dass die Bilder nicht mehr angezeigt und auch nicht vergrößert dargestellt werden können. Abhilfe: Der Name der importierten Tabelle wird geändert und die gesamte Tabelle wird kopiert. Beim Einfügen wird die Tabelle mit altem Namen neu erstellt. Jetzt wird beim Datentyp für das Bild der Datentyp Blob [BLOB] gewählt. Dieser Datentyp zeigt Bilder (und ggf. auch andere Dokumente) wieder korrekt an.
Vor allem bei Zahlenwerten besteht große Verwechselungsgefahr. In der Datenbank steht z.B. häufig im Primärschlüssel der Datentyp «INTEGER». Wird jetzt per Makro ausgelesen, so muss dort die aufnehmende Variable den Typ «Long» haben, da diese vom Umfang her mit «INTEGER» aus der Datenbank übereinstimmt. Der entsprechende Auslesebefehl heißt dann auch «getLong».
In der eingebauten HSQLDB bzw. in Firebird sind die folgenden Funktionen verfügbar. Ein paar Funktionen können leider nur dann genutzt werden, wenn in der Abfrage «SQL-Kommando direkt ausführen» gewählt wurde. Dies verhindert dann gleichzeitig, dass die Abfragen editierbar bleiben.
Funktionen, die mit der grafischen Benutzeroberfläche zusammenarbeiten, sind gekennzeichnet mit GUI. Funktionen, die nur über «SQL-Kommando direkt ausführen» ansprechbar sind, sind gekennzeichnet mit GUI.
Bei den Funktionen gibt es solche, die mit der HSQLDB laufen, nicht aber mit der eingebauten Version von Firebird - und umgekehrt. Ist der Datenbankname grün dargestellt, so ist die Funktion verfügbar und gibt ordnungsgemäße Werte aus. Ist der Datenbankname rot und durchgestrichen dargestellt, so ist die Funktion nicht verfügbar oder aber, was deutlich bedenklicher ist, verfügbar, nur eben mit falschen Ergebnissen. Das ist dann mit dem Zusatz (Bug) gekennzeichnet.
Window-Funktionen bei FirebirdWindow-Funktionen2 filtern nicht die Ergebnismenge einer Abfrage. Die Ergebnisse der Funktionen werden zusätzlich in entsprechenden Spalten angegeben.
Window-Funktionen können in der SELECT-Liste oder in der ORDER BY-Definition vorkommen. In den Window-Funktionen ist eine OVER-Klausel zwingend enthalten. In dieser Klausel können Partitionierungen und Sortierungen vorgenommen werden. <Funktionsname>() OVER (PARTITION BY … | ORDER BY …) | |
Ranking-Funktionen | |
RANK() OVER (ORDER BY …) |
Kann zur Bestimmung der Reihenfolge in einer Datenmenge eingesetzt werden. Gleiche Werte werden dabei mit der gleichen Position versehen. Die Position wird wie bei Sportwettkämpfen erstellt. Richtet sich nach der Sortierung, die angegeben wird. |
RANK() OVER (PARTITION BY … ORDER BY …) |
Gleiche Funktion wie oben, nur mit der Ergänzung der Partitionierung. Hier ist die Reihenfolge abhängig vom Feld "Geschlecht". |
DENSE_RANK() OVER (ORDER BY …) |
Kann zur Bestimmung der Reihenfolge in einer Datenmenge eingesetzt werden. Gleiche Werte werden dabei mit der gleichen Position versehen. Dabei rücken tiefer liegende Werte auf. Richtet sich nach der Sortierung, die angegeben wird. |
ROW_NUMBER() OVER (ORDER BY …) |
Kann zur Bestimmung der laufenden Nummer in einer Datenmenge eingesetzt werden. Gleiche Werte werden dabei nach dem Primärschlüssel zusätzlich sortiert. Richtet sich nach der Sortierung, die angegeben wird. |
Navigationsfunktionen | |
FIRST_VALUE(…) OVER (ORDER BY …) |
Hier wird der Wert für die niedrigste Laufzeit neben angezeigten aktuellen Laufzeit angegeben. Es könnte also direkt die Differenz zum ersten Platz ausgerechnet werden. |
LAG(…,[offset,[default]]) OVER (ORDER BY …) |
Hier wird der Wert für die Laufzeit angezeigt, die die Person gelaufen hat, die direkt vorher ins Ziel gekommen ist. Es könnte also direkt die Differenz zur vorher durchs Zeile gekommenen Person ausgerechnet werden. |
LAST_VALUE(…) OVER (ORDER BY …) |
Hier wird der zuletzt ausgelesene Wert wieder gegeben. Dies ist also nicht der Wert für die zuletzt durchs Ziel gekommene Person, sondern der aktuelle Wert, der auch so in der Laufzeit steht. |
LEAD(…,[offset,[default]]) OVER (ORDER BY …) |
Dies ist die Umkehrung der Funktion von LAG. Es wird die Zeit angezeigt, die die Person gelaufen ist, die direkt nach der aktuellen Position ins Ziel gekommen ist. |
NTH_VALUE(…,offset) [FROM {FIRST | LAST}] OVER (ORDER BY …) |
Ein offset muss angegeben werden. Die obige Abfrage gibt mit dem offset '1' genau das gleiche Ergebnis wie FIRST_VALUE, kann durch das offset aber auf die verschiedenen anderen Werte eingestellt werden. Standardmäßig wird vom ersten Wert (FROM FIRST) aus ermittelt. Ansonsten vom zuletzt ermittelten Wert. |
Aggregatfunktionen als WindowfunktionenAlle Aggregatfunktionen können auch als Windowfunktionen erstellt werden. Damit entfällt die Gruppierungsanweisung (die darüber hinaus die einzelnen Datensätze nicht mehr komplett anzeigt) oder die Notwendigkeit, innerhalb einer Abfrage eine separate Unterabfrage zu erstellen. Alle Aggregatfunktionen können genutzt werden. Hier nur ein Beispiel für die Nutzung von SUM. | |
SUM(…) OVER (PARTITION BY …) |
Die Summierung erfolgt nach der Ausgabe des gesamten Inhaltes der Tabelle. Keine Feld muss gruppiert werden. Die Summe wird für das Feld "Betrag" abhängig von der "RechnungsNr" berechnet. |
SUM(…) OVER (PARTITION BY … ORDER BY …) |
Wird zusätzlich eine Sortierung vorgenommen, so wird die laufende Summe ermittelt. In der 2. Zeile also die Summe von Zeile 1 und 2, in der 3. Zeile dann die Summe von Zeile 1 und 2 und 3. |
Die folgenden Probleme können bei der Migration von Datenbanken der internen HSQLDB 1.8.0.10 zu der internen Firebird 3.0 auftauchen.
•Tabellennamen, Spaltennamen usw. sind in der HSQLDB von der Länge nicht begrenzt. Bei Firebird hingegen gilt eine Grenze von maximal 31 Zeichen.
•Texttabellen können in der HSQLDB zum Lesen, Schreiben und Ändern von Daten genutzt werden. Zur Zeit funktionieren Texttabelle in Firebird hingegen gar nicht, weil die Standardeinstellungen dafür bei der internen Datenbank ausgeschaltet sind. Selbst bei funktionierenden Texttabellen unterscheidet sich das Format der Tabellen, so dass z.B. keine *.csv-Dateien benutzt werden können. Außerdem ist das Ändern und Löschen von Daten in Firebird-Texttabellen nicht erlaubt.
•Unterformulare funktionieren nach der Nutzung des Migrationsassistenten nicht. Hier muss die Datenbankdatei mit einem Packprogramm geöffnet werden. Die content.xml muss zum Bearbeiten geöffnet werden. Der Eintrag <db:driver-settings db:system-driver-settings="" db:base-dn="" db:parameter-name-substitution="false"/> benötigt statt des false ein true. Entweder ist hier also true einzutragen oder der gesamte Inhalt db:parameter-name-substitution="false" zu löschen.
Alternativ kann auch das folgende Makro von der migrierten Base-Datei aus gestartet werden:
SUB FB_Parameter
DIM oSettings AS OBJECT
oSettings = ThisComponent.DataSource.Settings
oSettings.ParameterNameSubstitution = True
END SUB
Nach einmaligem Start des Makros ist der Eintrag in der Base-Datei komplett verschwunden, wenn die Base-Datei anschließend abgespeichert wird.
•Sollen Bilder in der Datenbank gespeichert werden, so ist der Datentyp BLOB [BLOB] statt Bild [BLOB] zu währen. Nur Inhalte aus BLOB [BLOB] werden im grafischen Kontrollfeld angezeigt.
Hinweis
001 SUB FirebirdMigrationRemove
002 DIM oDoc AS OBJECT
003 DIM oDataSource AS OBJECT
004 DIM oSettings AS OBJECT
005 DIM oDocumentSubStorage AS OBJECT
006 DIM sURL AS STRING
007 oDoc = ThisComponent
008 sURL = "sdbc:embedded:hsqldb"
009 oDataSource = ThisComponent.DataSource
010 oDataSource.URL = sURL
011 oSettings = oDataSource.Settings
012 oSettings.JavaDriverClassPath = sURL
013 REM 4 = write mode
014 oDocumentSubStorage = oDoc.getDocumentSubStorage("database", 4)
015 oDocumentSubStorage.removeElement("firebird.fbk")
016 oDocumentSubStorage.commit()
017 END SUB
Im Folgenden sind Funktionen aufgelistet, die in Firebird nicht mit dem gleichen Namen existieren. Die erste Spalte enthält die Funktionsbezeichnung bei der Hsqldb, die zweite Spalte Funktionsbezeichnungen, die alternativ in der Hsqldb und in Firebird verwendet werden können. Existiert so eine Alternative nicht, so muss die dritte Spalte greifen, die Funktionen beschreibt, die in Firebird die gleiche Bedeutung haben wie die Funktionen der Hsqldb in der ersten Spalte.
HSQLDB |
HSQLDB und Firebird |
Firebird |
BITAND(a,b) |
|
BIN_AND(a,b) |
BITOR(a,b) |
|
BIN_OR(a,b) |
BITXOR(a,b) |
|
BIN_XOR(a,b) |
DEGREES(d) |
<value for radians>*360/(2*PI()) |
|
LOG(d) |
|
LN(d) |
RADIANS(d) |
<value for degrees>*2*PI()/360 |
|
ROUNDMAGIC(d) |
|
Keine Funktion vorhanden |
TRUNCATE(a,b) |
|
TRUNC(a,b) |
HSQLDB |
HSQLDB und Firebird |
Firebird |
ASCII(s) |
|
ASCII_VAL(s) |
BIT_LENGTH(s) |
Gibt die Texlänge wieder. Gleiche Funktion, aber unterschiedliche Zählweise |
BIT_LENGTH(s) |
CHAR(c) |
|
ASCII_CHAR© (nur 0 - 255) |
CONCAT(str1,str2) 'str1'+'str2'+'str3' |
'str1'||'str2'||'str3' |
|
DIFFERENCE(s1,s2) |
|
Keine Funktion vorhanden |
HEXTORAW(s) |
|
Keine Funktion vorhanden |
INSERT(s1,start,len,s2) |
|
OVERLAY(s1 PLACING s2 FROM start [FOR len]) |
LCASE(s) |
LOWER(s) |
|
LENGTH(s) |
CHAR_LENGTH(s) CHARACTER_LENGTH() |
|
LOCATE(search,s[,start]) |
POSITION(search IN s) |
POSITION(search,s[,start]) |
LTRIM(s) |
TRIM(LEADING FROM s) |
|
OCTET_LENGTH(s) |
Gleiche Funktion, aber unterschiedliche Zählweise |
OCTET_LENGTH(s) |
RAWTOHEX(s) |
|
Keine Funktion vorhanden |
REPEAT(s,count) |
|
Keine Funktion vorhanden |
RTRIM(s) |
TRIM(TRAILING FROM s) |
|
SOUNDEX(s) |
|
Keine Funktion vorhanden |
SPACE(count) |
|
Keine Funktion vorhanden |
SUBSTR(s,start[,len]) |
SUBSTRING(s FROM start [ FOR len]) |
|
UCASE(s) |
UPPER(s) |
|
HSQLDB |
HSQLDB und Firebird |
Firebird |
CURDATE(), TODAY |
CURRENT_DATE |
|
CURTIME() |
CURRENT_TIME |
|
DATEDIFF(string, datetime1, datetime2) |
|
DATEDIFF(string, datetime1, datetime2) |
DAY(date) |
EXTRACT(DAY FROM datetime) |
|
DAYNAME(date) |
|
Keine Funktion vorhanden |
DAYOFWEEK(date) |
|
EXTRACT(WEEKDAY FROM datetime) |
DAYOFYEAR(date) |
|
EXTRACT(YEARDAY FROM datetime) |
HOUR(time) |
EXTRACT(HOUR FROM datetime) |
|
MINUTE(time) |
EXTRACT(MINUTE FROM datetime) |
|
MONTH(date) |
EXTRACT(MONTH FROM datetime) |
|
MONTHNAME(date) |
|
Keine Funktion vorhanden |
NOW() |
CURRENT_TIMESTAMP |
|
QUARTER(date) |
CEILING(EXTRACT(MONTH FROM date)/3.00) |
|
SECOND(time) |
EXTRACT(SECOND FROM datetime) |
|
WEEK(date) |
|
EXTRACT(WEEK FROM datetime) |
YEAR(date) |
EXTRACT(YEAR FROM datetime) |
|
TO_CHAR(datetime, string) |
|
Keine Funktion vorhanden |
HSQLDB |
HSQLDB und Firebird |
Firebird |
DATABASE() |
|
RDB$GET_CONTEXT('SYSTEM', 'DB_NAME') |
USER() |
CURRENT_USER |
|
IDENTITY() |
|
Keine Funktion vorhanden |
HSQLDB |
HSQLDB und Firebird |
Firebird |
IFNULL(exp,value) |
COALESCE(expr1,expr2,expr3,...) |
|
CASEWHEN(exp,v1,v2) |
CASE WHEN expr1 THEN v1[WHEN expr2 THEN v2] [ELSE v4] END |
IIF(exp,v1,v2) |
CONVERT(term,type) |
CAST(term AS type) |
|
In Abfragen lassen sich Felder miteinander verknüpfen. Aus zwei Feldern in
001 SELECT "Vorname", "Nachname" FROM "Tabelle"
wird durch
001 SELECT "Vorname"||' '||"Nachname" FROM "Tabelle"
ein Feld. Hier wird noch ein Leerzeichen mit eingefügt. Natürlich lassen sich hier alle möglichen beliebigen Zeichen einfügen. Solange diese in '' stehen werden sie als Text interpretiert. Manchmal ist es aber auch sinnvoll, Zeilenumbrüche z.B. für einen Bericht einzufügen. Deshalb hier eine kleine Liste von Steuerzeichen, die entsprechend durch einen Blick auf http://de.wikipedia.org/wiki/Steuerzeichen erweitert werden kann.
CHAR( 9 ) |
Horizontaler Tabulator |
|
CHAR( 10 ) |
Zeilenvorschub |
Erzeugt in Serienbriefen und im Report-Builder in einem Feld einen Zeilenumbruch (Linux, Unix, Mac) Um den Zeilenumbruch auch in Abfragen anzuzeigen, muss das Feld in ein LONGVARCHAR-Feld umgewandelt werden. |
CHAR( 13 ) |
Wagenrücklauf |
Zeilenumbruch zusammen mit dem Zeilenvorschub in Windows. |
Bei Firebird ist statt CHAR( ) ASCII_CHAR( ) erforderlich.
Einer Schaltfläche können verschiedene uno-Befehle direkt zugeordnet werden. Dafür muss unter Eigenschaften: Schaltfläche → Aktion → Dokument/Webseite öffnen gewählt werden sowie z. B. als URL → .uno:RecSearch zum Öffnen der Suchfunktion eingetragen werden. Manchmal muss zusätzlich beachtet werden, dass Fokussieren bei Klick → Nein angewählt wird, wenn bestimmte Aktionen direkt auf ein Formularfeld zugreifen sollen, das dafür den Focus braucht, wie z. B. .uno:Paste, das den Inhalt aus der Zwischenablage einfügen kann.
Die folgende Liste gibt nur wenige Befehle wieder. Sämtliche Befehle aus der Navigationsleiste sind ja bereits in der Schaltfläche so verfügbar, könnten aber auch über die uno-Befehle erstellt werden. Viele Befehle lassen sich auch über den Makrorekorder ermitteln, der häufig diese uno-Befehle über einen Dispatcher aufruft. UNO-Befehle können auch z. B. über Extras → Anpassen → Symbolleisten → Beschreibung in jedem LO-Dokument ermittelt werden.
Uno-Befehl |
Anwendung für ... |
.uno:RecSearch |
Öffnen der Suchfunktion im Formular |
.uno:Paste |
Zwischenablage einfügen, nur mit Fokussieren bei Klick → Nein |
.uno:Copy |
Kopiert den markierten Inhalt in die Zwischenablage, nur mit Fokussieren bei Klick → Nein |
.uno:Print |
Druckdialog für das Formular öffnen |
.uno:PrintDefault |
Drucken mit dem Standarddrucker ohne Dialog |
.uno:NextRecord |
Nächster Datensatz |
.uno:PrevRecord |
Vorhergehender Datensatz |
.uno:FirstRecord |
Erster Datensatz |
.uno:LastRecord |
Letzter Datensatz |
.uno:NewRecord |
Neuer Datensatz |
.uno:RecSave |
Datensatz speichern |
.uno:DeleteRecord |
Lösche den Datensatz |
.uno:RecUndo |
Nehme die letzten Eingaben zurück. |
.uno:OpenURL |
Öffne die angezeigte URL |
.uno:Refresh |
Angezeigte Daten aktualisieren |
.uno:ViewFormAsGrid |
Formular: Datenquelle als Tabelle aufrufen |
Innerhalb von HSQLDB-Datenbanken wird in dem Bereich "INFORMATION_SCHEMA" die Information über alle Tabelleneigenschaften sowie ihre Verbindung untereinander abgelegt. Diese Informationen ermöglichen in Base bei der Erstellung von Makros, Prozeduren mit weniger Parametern zu starten. Eine Anwendung findet sich in der Beispieldatenbank unter anderem im Modul «Wartung» in der Prozedur «Tabellenbereinigung» für die Ansteuerung des Dialoges.
In einer Abfrage können die einzelnen Informationen sowie sämtliche dazugehörigen Felder auf die folgende Art ermittelt werden.
001 SELECT * FROM "INFORMATION_SCHEMA"."SYSTEM_ALIASES"
Im Gegensatz zu einer normalen Tabelle ist es hier notwendig, dem jeweiligen folgenden Begriff "INFORMATION_SCHEMA" voranzustellen.
SYSTEM_ALIASES
SYSTEM_ALLTYPEINFO
SYSTEM_BESTROWIDENTIFIER
SYSTEM_CACHEINFO
SYSTEM_CATALOGS
SYSTEM_CHECK_COLUMN_USAGE
SYSTEM_CHECK_CONSTRAINTS
SYSTEM_CHECK_ROUTINE_USAGE
SYSTEM_CHECK_TABLE_USAGE
SYSTEM_CLASSPRIVILEGES
SYSTEM_COLUMNPRIVILEGES
SYSTEM_COLUMNS
SYSTEM_CROSSREFERENCE
SYSTEM_INDEXINFO
SYSTEM_PRIMARYKEYS
SYSTEM_PROCEDURECOLUMNS
SYSTEM_PROCEDURES
SYSTEM_PROPERTIES
SYSTEM_SCHEMAS
SYSTEM_SEQUENCES
SYSTEM_SESSIONINFO
SYSTEM_SESSIONS
SYSTEM_SUPERTABLES
SYSTEM_SUPERTYPES
SYSTEM_TABLEPRIVILEGES
SYSTEM_TABLES
SYSTEM_TABLETYPES
SYSTEM_TABLE_CONSTRAINTS
SYSTEM_TEXTTABLES
SYSTEM_TRIGGERCOLUMNS
SYSTEM_TRIGGERS
SYSTEM_TYPEINFO
SYSTEM_UDTATTRIBUTES
SYSTEM_UDTS
SYSTEM_USAGE_PRIVILEGES
SYSTEM_USERS
SYSTEM_VERSIONCOLUMNS
SYSTEM_VIEWS
SYSTEM_VIEW_COLUMN_USAGE
SYSTEM_VIEW_ROUTINE_USAGE
SYSTEM_VIEW_TABLE_USAGE
Die folgende Abfrage gibt z.B. eine komplette Übersicht über alle in der Datenbank genutzten Tabellen mit Feldtypen, Primärschlüsseln und Fremdschlüsseln:
001 SELECT
002 "A"."TABLE_NAME",
003 "A"."COLUMN_NAME",
004 "A"."TYPE_NAME",
005 "A"."NULLABLE",
006 "B"."KEY_SEQ" AS "PRIMARYKEY",
007 "C"."PKTABLE_NAME" || '.' || "C"."PKCOLUMN_NAME" AS "FOREIGNKEY FOR"
008 FROM "INFORMATION_SCHEMA"."SYSTEM_COLUMNS" AS "A"
009 LEFT JOIN "INFORMATION_SCHEMA"."SYSTEM_PRIMARYKEYS" AS "B"
010 ON ( "B"."TABLE_NAME" = "A"."TABLE_NAME" AND "B"."COLUMN_NAME" =
"A"."COLUMN_NAME" )
011 LEFT JOIN "INFORMATION_SCHEMA"."SYSTEM_CROSSREFERENCE" AS "C"
012 ON ( "C"."FKTABLE_NAME" = "A"."TABLE_NAME" AND "C"."FKCOLUMN_NAME" =
"A"."COLUMN_NAME" )
013 WHERE "A"."TABLE_SCHEM" = 'PUBLIC'
Die Firebird-Informationstabellen sind deutlich mehr gesplittet als die der HSQLDB. So stehen z.B. Tabellennamen, Feldnamen und Feldtypen nicht zusammen in einer Tabelle, sondern müssen über mehrere Tabellen hinweg zusammen gebracht werden:
001 SELECT
002 "a".RDB$RELATION_NAME AS "Tables",
003 "a".RDB$FIELD_NAME AS "Fields",
004 "c".RDB$TYPE_NAME AS "Types",
005 "a".RDB$Field_POSITION AS "Fieldposition",
006 "a".RDB$NULL_FLAG AS "Nullflag"
007 FROM RDB$RELATION_FIELDS AS "a", RDB$FIELDS AS "b", RDB$TYPES AS "c"
008 WHERE "a".RDB$FIELD_SOURCE = "b".RDB$FIELD_NAME
009 AND "b".RDB$FIELD_TYPE = "c".RDB$TYPE
010 AND "c".RDB$FIELD_NAME = 'RDB$FIELD_TYPE'
011 AND "a".RDB$SYSTEM_FLAG = 0
012 ORDER BY "Tables", "Fieldposition"
Hiermit wird eine Übersicht über alle selbst erstellten Tabellen mit den Feldnamen, Feldtypen, Feldpositionen innerhalb der Tabelle und der Information, ob sie leer sein dürfen, ermöglicht. Um den Feldtypen zuordnen zu können muss also über die Tabelle "RDB$FIELD_TYPE" zur Tabelle "RDB$TYPE" verbunden werden.
Leider stimmen die dort aufgeführten Typen nur mit denen überein, die intern von Firebird genutzt werden. Sie lauten anders als die, die in dem Tabelleneditor vorkommen. Hier ein Code, um die entsprechende Übersicht zu bekommen, die nur über Nummern aus den Informationstabellen auslesbar ist:
001 SELECT TRIM("a".RDB$RELATION_NAME) AS "Tabelle",
002 "a".RDB$FIELD_NAME AS "Feld",
003 TRIM(CASE "b".RDB$FIELD_TYPE||'|'|| COALESCE("b".RDB$FIELD_SUB_TYPE,0)
004 WHEN '7|0' THEN 'SMALLINT'
005 WHEN '8|0' THEN 'INTEGER'
006 WHEN '8|1' THEN 'NUMERIC'
007 WHEN '8|2' THEN 'DECIMAL'
008 WHEN '10|0' THEN 'FLOAT'
009 WHEN '12|0' THEN 'DATE'
010 WHEN '13|0' THEN 'TIME'
011 WHEN '14|0' THEN 'CHAR'
012 WHEN '16|0' THEN 'BIGINT'
013 WHEN '27|0' THEN 'DOUBLE PRECISION'
014 WHEN '35|0' THEN 'TIMESTAMP'
015 WHEN '37|0' THEN 'VARCHAR'
016 WHEN '261|0' THEN 'BLOB'
017 WHEN '261|1' THEN 'BLOB Text'
018 WHEN '261|2' THEN 'BLOB BLR'
019 WHEN '261|3' THEN 'BLOB ACL'
020 END) AS "SQL_Datentyp",
021 COALESCE(
022 "b".RDB$CHARACTER_LENGTH,
023 "b".RDB$FIELD_PRECISION||','||
024 ("b".RDB$FIELD_SCALE*-1)) AS "Laenge,Nachkommastellen"
025 FROM RDB$RELATION_FIELDS AS "a", RDB$FIELDS AS "b"
026 WHERE "a".RDB$FIELD_SOURCE = "b".RDB$FIELD_NAME
027 AND "a".RDB$SYSTEM_FLAG = 0
Diese Abfrage gibt alle genutzten Tabellen mit den Feldnamen, den Feldtypen und der Feldlänge bzw. Genauigkeit bei Dezimalzahlen an.
Die Ausgabe in dieser Abfrage erfolgt in festen Spaltenbreiten. Von der HSQLDB ist es eher so, dass nur die Anzahl der lesbaren Zeichen wiedergegeben werden. Falls also eine Ausgabe nach den Bezeichnern ausgewertet werden soll, so sind die Leerzeichen durch TRIM zu entfernen.
Automatisch generierte Werte wie in der HSQLDB werden bei Firebird über Generatoren erstellt. Um den Startwert eines solchen Generators neu einstellen zu können ist der Name des Generators erforderlich. Die folgende Abfrage liefert den Generatornamen für alle Tabellen, die von dem Nutzer erstellt wurden:
001 SELECT RDB$FIELD_NAME, RDB$RELATION_NAME, RDB$GENERATOR_NAME
002 FROM RDB$RELATION_FIELDS
003 WHERE RDB$GENERATOR_NAME IS NOT NULL
Ansichten werden auch von Firebird unterstützt. Die folgende Abfrage liefert den Namen und die SQL-Formulierung für jede Ansicht:
001 SELECT RDB$RELATION_NAME, RDB$VIEW_SOURCE
002 FROM RDB$RELATIONS
003 WHERE RDB$VIEW_SOURCE IS NOT NULL
Die Firebird-Systemtabellen starten alle mit den Anfangsbuchstaben RDB$:
RDB$BACKUP_HISTORY
RDB$CHARACTER_SETS
RDB$CHECK_CONSTRAINTS
RDB$COLLATIONS
RDB$DATABASE
RDB$DEPENDENCIES
RDB$EXCEPTIONS
RDB$FIELDS
RDB$FIELD_DIMENSIONS
RDB$FILES
RDB$FILTERS
RDB$FORMATS
RDB$FUNCTIONS
RDB$FUNCTION_ARGUMENTS
RDB$GENERATORS
RDB$INDICES
RDB$INDEX_SEGMENTS
RDB$LOG_FILES
RDB$PAGES
RDB$PROCEDURES
RDB$PROCEDURE_PARAMETERS
RDB$REF_CONSTRAINTS
RDB$RELATIONS
RDB$RELATION_CONSTRAINTS
RDB$RELATION_FIELDS
RDB$ROLES
RDB$SECURITY_CLASSES
RDB$TRANSACTIONS
RDB$TRIGGERS
RDB$TRIGGER_MESSAGES
RDB$TYPES
RDB$USER_PRIVILEGES
RDB$VIEW_RELATIONS
Regelmäßige Datensicherung sollte eigentlich Grundlage für den Umgang mit dem PC sein. Sicherheitskopien sind so der einfachste Weg, auf einen halbwegs aktuellen Datenstand zurückgreifen zu können. Doch in der Praxis mangelt es eben häufig an dieser Stelle.
Formulare, Abfragen und Berichte können, sofern eine Vorversion der Datenbank gesichert wurde, über die Zwischenablage in eine neue Datenbank kopiert werden. Lässt sich allerdings, aus welchen Gründen auch immer, eine aktuelle Datenbankdatei nicht mehr öffnen, so ist das Hauptproblem: Wie komme ich (hoffentlich) an die Daten.
Hinweis
Bevor es an die Wiederherstellung einer Datenbank-Archivdatei geht sollte erst einmal geklärt werden, ob nicht irgendwo im System doch eine Sicherungskopie existiert, die nicht bewusst angelegt wurde.
Eine Möglichkeit ist der Backup-Pfad von LibreOffice: Extras → Optionen → LibreOffice → Pfade → Sicherungskopien gibt darüber Aufschluss. Falls dieser Pfad noch nicht existiert wurde er noch nicht genutzt.
Eine weitere Möglichkeit ist das temporäre Verzeichnis des Betriebssystems: Extras → Optionen → LibreOffice → Pfade → Temporäre Dateien dürfte hier den richtigen Pfad angeben. Unter Linux ist dies /tmp. In diesem Pfad befinden sich Verzeichnisse, die mit lu….tmp gekennzeichnet sind, also von der Namensgebung so aussehen, als wären es Dateinamen mit der Endung «tmp». In diesen Pfaden befinden sich Dateien von LibreOffice, sofern die Dateien gerade geöffnet sind und bearbeitet werden. Wird LibreOffice normal beendet, so werden diese Pfade wieder gelöscht. Alte Pfade weisen also darauf hin, dass das Programm zu dem Zeitpunkt nicht korrekt beendet wurde. Leider haben die Dateien in diesen Pfaden nicht die ursprünglichen Namen. Unter Linux lassen sich aber Dateitypen auch mit der Endung *.tmp problemlos den Programmtypen zuordnen.
Bei plötzlichen Abstürzen des PC kann es passieren, dass geöffnete Datenbanken von LO (interne Datenbank HSQLDB) nicht mehr zu öffnen sind. Stattdessen wird beim Versuch, die Datenbank zu öffnen, nach einem entsprechenden Filter für das Format gefragt.
Das Ganze liegt daran, dass Teile der Daten der geöffneten Datenbank im Arbeitsspeicher liegen und lediglich temporär zwischengespeichert werden. Oft wird erst beim Schließen der Datei die gesamte Datenbank in die Datei zurückgeschrieben und gepackt. Lediglich Eingaben, die direkt in die Tabellen erfolgen, werden auch direkt in die Datenbankdatei gesichert. Seit LO 5.1 kann außerdem die Datenbank noch über den Button Speichern gesichert werden. Dies war vorher nicht der Fall, da der Button nicht den Zugang zu einem Untermenü anbot und deshalb inaktiv war.
Um eventuell doch noch an die Daten zu kommen, kann das folgende Verfahren hilfreich sein:
1.Fertigen sie eine Kopie ihrer Datenbank für die weiteren Schritte an.
2.Versuchen Sie die Kopie mit einem Packprogramm zu öffnen. Es handelt sich bei der *.odb‑Datei um ein gepacktes Format, ein Zip-Archiv. Lässt sich die Datei so nicht direkt öffnen, so funktioniert das Ganze vielleicht auch über die Umbenennung der Endung von *.odb zu *.zip.
Funktioniert das Öffnen nicht, so ist vermutlich von der Datenbank nichts mehr zu retten.
3.Folgende Verzeichnisse sehen Sie nach dem Öffnen einer Datenbankdatei im Packprogramm auf jeden Fall:
4.Die Datenbankdatei muss ausgepackt werden. Die entscheidenden Informationen für die Daten liegen im Unterverzeichnis «database» in den Dateien «data» und «script».
5.Gegebenenfalls empfiehlt es sich, die Datei «script» einmal anzuschauen und auf Ungereimtheiten zu überprüfen. Dieser Schritt kann aber auch erst einmal zum Testen übersprungen werden. Die «script»-Datei enthält vor allem die Beschreibung der Tabellenstruktur.
6.Gründen sie eine neue, leere Datenbankdatei und öffnen diese Datenbankdatei mit dem Packprogramm.
7.Ersetzen sie die Dateien «data» und «script» aus der neuen Datenbankdatei durch die unter «4.» entpackten Dateien.
8.Das Packprogramm muss nun geschlossen werden. War es, je nach Betriebssystem, notwendig, die Dateien vor dem Öffnen durch das Packprogramm nach *.zip umzubenennen, so ist das jetzt wieder nach *.odb zu wandeln.
9.Öffnen sie die Datenbankdatei jetzt mit LO. Sie können hoffentlich wieder auf ihre Tabellen zugreifen.
10.Wie weit sich jetzt auch Abfragen, Formulare und Berichte auf ähnliche Weise wiederherstellen lassen, bleibt dem weiteren Testen überlassen.
Siehe hierzu auch: http://user.services.LO oder Ooo.org/en/forum/viewtopic.php?f=83&t=17125
Eine Datenbank-Archivdatei enthält im tatsächlichen Gebrauch neben dem grundlegenden Verzeichnis für die Datenbank und dem für das OpenDocument-Format vorgeschriebenen Verzeichnis «META-INF» noch weitere Verzeichnisse, um Formulare und Berichte abzuspeichern. Eine Beschreibung zum grundsätzliche Aufbau des OpenDocument-Formates ist u.a. unter http://de.wikipedia.org/wiki/OpenDocument zu finden.
Die folgende Übersicht zeigt eine Datenbank, die Tabellen ein Formular und einen Bericht enthält. Nicht offen sichtbar ist hier, dass auch eine Abfrage zur Datenbank gehört. Solche Abfragen werden nicht in separaten Verzeichnissen gespeichert, sondern sind in der Datei «content.xml» enthalten. Die dafür notwendigen Informationen beschränken sich schließlich auf eine einfache SQL-Formulierung.
Hier einige der Dateien aus der Datenbank-Archivdatei im Überblick:
mimetype
004 application/vnd.oasis.opendocument.base
Diese kleine Textdatei enthält lediglich den Hinweis, dass es sich bei der Archivdatei um eine Datenbankdatei im OpenDocument-Format handelt.
content.xml einer Datenbank ohne Inhalt
005 <?xml version="1.0" encoding="UTF-8"?>
<office:document-content
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:draw="urn:oasis:names:tc:opendocument:xmlns:drawing:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:meta="urn:oasis:names:tc:opendocument:xmlns:meta:1.0" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="urn:oasis:names:tc:opendocument:xmlns:svg-compatible:1.0" xmlns:chart="urn:oasis:names:tc:opendocument:xmlns:chart:1.0" xmlns:dr3d="urn:oasis:names:tc:opendocument:xmlns:dr3d:1.0" xmlns:math="http://www.w3.org/1998/Math/MathML"
xmlns:form="urn:oasis:names:tc:opendocument:xmlns:form:1.0" xmlns:script="urn:oasis:names:tc:opendocument:xmlns:script:1.0"
xmlns:ooo="http://openoffice.org/2004/office"
xmlns:ooow="http://openoffice.org/2004/writer"
xmlns:oooc="http://openoffice.org/2004/calc"
xmlns:dom="http://www.w3.org/2001/xml-events"
xmlns:db="urn:oasis:names:tc:opendocument:xmlns:database:1.0" xmlns:xforms="http://www.w3.org/2002/xforms"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:rpt="http://openoffice.org/2005/report"
xmlns:of="urn:oasis:names:tc:opendocument:xmlns:of:1.2" xmlns:xhtml="http://www.w3.org/1999/xhtml"
xmlns:grddl="http://www.w3.org/2003/g/data-view#"
xmlns:tableooo="http://openoffice.org/2009/table"
xmlns:drawooo="http://openoffice.org/2010/draw"
xmlns:calcext="urn:org:documentfoundation:names:experimental:calc:xmlns:calcext:1.0"
xmlns:field="urn:openoffice:names:experimental:ooo-ms-interop:xmlns:field:1.0" xmlns:formx="urn:openoffice:names:experimental:ooxml-odf-interop:xmlns:form:1.0" xmlns:css3t="http://www.w3.org/TR/css3-text/"
office:version="1.2">
<office:scripts/>
<office:font-face-decls/>
<office:automatic-styles/>
<office:body>
<office:database>
<db:data-source>
<db:connection-data>
<db:connection-resource xlink:href="sdbc:embedded:hsqldb"/>
<db:login db:is-password-required="false"/>
</db:connection-data>
<db:driver-settings
db:system-driver-settings=""
db:base-dn=""
db:parameter-name-substitution="false"/>
<db:application-connection-settings
db:is-table-name-length-limited="false"
db:append-table-alias-name="false"
db:max-row-count="100">
<db:table-filter>
<db:table-include-filter>
<db:table-filter-pattern>%</db:table-filter-pattern>
</db:table-include-filter>
</db:table-filter>
</db:application-connection-settings>
</db:data-source>
</office:database>
</office:body>
</office:document-content>
Zu Beginn wird die xml-Version und der verwendete Zeichensatz geklärt. Der gesamte nachfolgende Inhalt wird ohne Absatz direkt in einer Zeile ausgegeben. In der oben erstellten Übersicht wird hoffentlich der Inhalt etwas klarer. Zusammengehörige Elemente werden in «Tags» gefasst.
Mit den Anfangsdefinitionen werden durch «xmlns» (XML-Namespace) die Namensräume umschrieben, auf die innerhalb dieser Datei zugegriffen werden kann. Anschließend werden etwas konkretere Angaben zum Inhalt gemacht. Hier ist dann z.B. ersichtlich, dass es sich um eine interne HSQLDB-Datenbank handelt und die Angabe eines Passwortes nicht erforderlich ist.
content.xml einer Datenbank mit Inhalt
Der folgende Inhalt ist nur ein Auszug der content.xml-Datei und soll nur die Struktur klären.
006 <office:scripts/>
<office:font-face-decls>
<style:font-face style:name="F" svg:font-family=""/>
</office:font-face-decls>
<office:automatic-styles>
<style:style
style:name="co1"
style:family="table-column"
style:data-style-name="N0"/>
<style:style
style:name="co2"
style:family="table-column"
style:data-style-name="N107"/>
<style:style style:name="ce1" style:family="table-cell">
<style:paragraph-properties fo:text-align="start"/>
</style:style>
<number:number-style style:name="N0" number:language="de" number:country="DE">
<number:number number:min-integer-digits="1"/>
</number:number-style>
<number:currency-style
style:name="N107P0"
style:volatile="true"
number:language="de"
number:country="DE">
<number:number
number:decimal-places="2"
number:min-integer-digits="1"
number:grouping="true"/>
<number:text> </number:text>
<number:currency-symbol
number:language="de"
number:country="DE">€
</number:currency-symbol>
</number:currency-style>
Hier wird ein Feld als Währungsfeld festgelegt. Die Anzahl der Dezimalstellen werden genannt, der Abstand zwischen Zahlen und Währungssymbol sowie das Währungssymbol selbst.
007 <number:currency-style
style:name="N107"
number:language="de"
number:country="DE">
<style:text-properties fo:color="#ff0000"/>
<number:text>-</number:text>
<number:number
number:decimal-places="2"
number:min-integer-digits="1"
number:grouping="true"/>
<number:text> </number:text>
<number:currency-symbol
number:language="de"
number:country="DE">€
</number:currency-symbol>
<style:map style:condition="value()>=0" style:apply-style-name="N107P0"/>
</number:currency-style>
Im zweiten Abschnitt erfolgt die Festlegung, dass bis zu einem bestimmten Wert die Währung in der Farbe Rot («#ff0000») erscheinen soll.
008 </office:automatic-styles>
<office:body>
<office:database>
<db:data-source>
Dieser Eintrag entspricht mit allen Unterpunkten dem aus der oben beschriebenen content.xml einer Datenbank-Archivdatei ohne Inhalt.
009 </db:data-source>
<db:forms>
<db:component
db:name="Quittung"
xlink:href="forms/Obj12"
db:as-template="false"/>
</db:forms>
Die Datenbank-Archivdatei enthält einen Unterordner, in dem die Details zu einem Formular abgespeichert sind. Das Formular ist auf der Benutzeroberfläche mit dem Namen «Quittung» verzeichnet.
010 <db:reports>
<db:component
db: name="Quittung"
xlink:href="reports/Obj12"
db:as-template="false"/>
</db:reports>
Die Datenbank-Archivdatei enthält einen Unterordner, in dem die Details zu einem Bericht abgespeichert sind. Der Bericht ist auf der Benutzeroberfläche ebenfalls mit dem Namen «Quittung» verzeichnet.
011 <db:queries>
<db:query
db:name="Verkauf_berechnet"
db:command="SELECT "a".*, ( SELECT "Preis" *
"a"."Anzahl" FROM "Ware" WHERE
"ID" = "a"."Ware_ID" ) AS
"Anzahl*Preis" FROM "Verkauf" AS
"a""/>
</db:queries>
Sämtliche Abfragen werden direkt in der content.xml gespeichert. «"» steht dabei für ein doppeltes Anführungszeichen oben «"». Die oben stehende Abfrage ist in diesem Beispiel eigentlich recht umfangreich und besteht aus vielen korrelierenden Unterabfragen. Sie ist hier nur verkürzt wiedergegeben.
012 <db:table-representations>
<db:table-representation db:name="Quittung"/>
<db:table-representation db:name="Verkauf"/>
<db:table-representation db:name="Ware">
<db:columns>
<db:column
db:name="ID"
db:style-name="co1"
db:default-cell-style-name="ce1"/>
<db:column
db:name="MWSt"
db:style-name="co1"
db:default-cell-style-name="ce1"/>
<db:column
db:name="Preis"
db:help-message="Angabe als Nettopreis"
db:style-name="co2"
db:default-cell-style-name="ce1"/>
<db:column
db:name="Ware"
db:style-name="co1"
db:default-cell-style-name="ce1"/>
</db:columns>
</db:table-representation>
</db:table-representations>
Wie sollen verschiedene Tabellen von der Ansicht her erscheinen? An dieser Stelle wird das Erscheinungsbild bestimmter Spalten gespeichert; in diesem Beispiel wurden Einstellungen der Tabelle "Ware" mit ihren einzelnen Feldern "ID", "MWSt" usw. abgespeichert. Hier wurde zum einen beim Preis eine Zusatzinformation angegeben. Zum anderen ist eine Formatierung der Angabe vorgenommen worden. Der style-name 'co2' entspricht beim Preis dem style-name, der zu Beginn der content.xml definiert wurde und mit dem data-style-name 'N107' verbunden ist. Der data-style-name 'N107' wiederum verweist auf die Formatierung des Feldes als Währungsfeld.
013 </office:database>
</office:body>
Grundsätzlich ist in der content.xml der Inhalt der Abfragen und Informationen zum Erscheinungsbild der Tabellen direkt gespeichert. Außerdem ist eine Definition der Verbindung zur Datenbank enthalten. Schließlich kommen noch Verweise auf Formulare und Berichte hinzu.
settings.xml
014 <?xml version="1.0" encoding="UTF-8"?>
<office:document-settings
xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:table="urn:oasis:names:tc:opendocument:xmlns:table:1.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:number="urn:oasis:names:tc:opendocument:xmlns:datastyle:1.0" xmlns:svg="http://www.w3.org/2000/svg" xmlns:config="urn:oasis:names:tc:opendocument:xmlns:config:1.0"
xmlns:ooo="http://openoffice.org/2004/office" xmlns:db="urn:oasis:names:tc:opendocument:xmlns:database:1.0"
office:version="1.2"/>
Bei einer Datenbank ohne weiteren Inhalt stehen hier nur die Grunddefinitionen. Mit Inhalt werden hier aber die unterschiedlichsten Einstellungen abgespeichert. Nach dem Start mit der obigen Definition sind folgende Einstellungen in der Beispieldatei abgespeichert:
015 <office:settings>
<config:config-item-set config:name="ooo:view-settings">
<config:config-item-set config:name="Queries">
<config:config-item-set config:name="Verkauf_berechnet">
<config:config-item-set config:name="Tables">
<config:config-item-set config:name="Table1">
<config:config-item config:name="WindowName"
config:type="string">Verkauf</config:config-item>
<config:config-item config:name="WindowLeft"
config:type="int">153</config:config-item>
<config:config-item config:name="ShowAll"
config:type="boolean">true</config:config-item>
<config:config-item config:name="WindowTop"
config:type="int">17</config:config-item>
<config:config-item config:name="WindowWidth"
config:type="int">120</config:config-item>
<config:config-item config:name="WindowHeight"
config:type="int">120</config:config-item>
<config:config-item config:name="ComposedName"
config:type="string">Verkauf</config:config-item>
<config:config-item config:name="TableName"
config:type="string">Verkauf</config:config-item>
</config:config-item-set>
</config:config-item-set>
<config:config-item config:name="SplitterPosition"
config:type="int">105</config:config-item>
<config:config-item config:name="VisibleRows"
config:type="int">1024</config:config-item>
</config:config-item-set>
</config:config-item-set>
</config:config-item-set>
<config:config-item-set config:name="ooo:configuration-settings">
<config:config-item-set config:name="layout-settings">
<config:config-item-set config:name="Tables">
<config:config-item-set config:name="Table1">
<config:config-item config:name="WindowName"
config:type="string">Verkauf</config:config-item>
<config:config-item config:name="WindowLeft"
config:type="int">186</config:config-item>
<config:config-item config:name="ShowAll"
config:type="boolean">false</config:config-item>
<config:config-item config:name="WindowTop"
config:type="int">17</config:config-item>
<config:config-item config:name="WindowWidth"
config:type="int">120</config:config-item>
<config:config-item config:name="WindowHeight"
config:type="int">120</config:config-item>
<config:config-item config:name="ComposedName"
config:type="string">Verkauf</config:config-item>
<config:config-item config:name="TableName"
config:type="string">Verkauf</config:config-item>
</config:config-item-set>
<config:config-item-set config:name="Table2">
... (identische config:type-Punkte wie "Table1"
<config:config-item config:name="TableName"
config:type="string">Ware</config:config-item>
</config:config-item-set>
<config:config-item-set config:name="Table3">
... (identische config:type-Punkte wie "Table1"
<config:config-item config:name="TableName"
config:type="string">Quittung</config:config-item>
</config:config-item-set>
</config:config-item-set>
</config:config-item-set>
</config:config-item-set>
</office:settings>
Die gesamte Übersicht bezieht sich auf verschiedene Ansichten der Fenster für die (eine) Abfrage "Verkauf berechnet" und für die Tabellen "Verkauf", "Ware" und "Quittung". Die letzten beiden wurden hier nur verkürzt wiedergegeben. Würden diese Einstellungen bei einer defekten *.odb-Datei fehlen, so wäre das also nicht weiter von Bedeutung. Sie würden wieder erstellt, wenn die entsprechenden Fenster das nächste Mal geöffnet werden.
META-INF/manifest.xml
016 <?xml version="1.0" encoding="UTF-8"?>
<manifest:manifest
xmlns:manifest="urn:oasis:names:tc:opendocument:xmlns:manifest:1.0">
<manifest:file-entry
manifest:full-path="/"
manifest:media-type="application/vnd.oasis.opendocument.base"/>
<manifest:file-entry
manifest:full-path="database/script"
manifest:media-type=""/>
<manifest:file-entry
manifest:full-path="database/properties"
manifest:media-type=""/>
<manifest:file-entry
manifest:full-path="settings.xml"
manifest:media-type="text/xml"/>
<manifest:file-entry
manifest:full-path="content.xml"
manifest:media-type="text/xml"/>
</manifest:manifest>
Bei dieser Datei im Unterverzeichnis META-INF handelt es sich um ein Inhaltsverzeichnis der gesamten Datenbank-Archivdatei. Da es sich bei der oben gezeigten Datei um die Datei handelt, die in der leeren Datenbank (1) enthalten ist, gibt es hier nur 5 Datei-Einträge («file-entry»). Bei der mit Formular und Bericht versehenen Datenbank-Archivdatei sind die Einträge in der META-INF entsprechend umfangreicher.
database/properties
017 #HSQL Database Engine 1.8.0.10
018 #Sun Jul 14 18:02:08 CEST 2013
019 hsqldb.script_format=0
020 runtime.gc_interval=0
021 sql.enforce_strict_size=true
022 hsqldb.cache_size_scale=8
023 readonly=false
024 hsqldb.nio_data_file=false
025 hsqldb.cache_scale=13
026 version=1.8.0
027 hsqldb.default_table_type=cached
028 hsqldb.cache_file_scale=1
029 hsqldb.lock_file=true
030 hsqldb.log_size=10
031 modified=no
032 hsqldb.cache_version=1.7.0
033 hsqldb.original_version=1.8.0
034 hsqldb.compatible_version=1.8.0
Die properties-Datei enthält die Grundeinstellungen für die interne HSQL Datenbank. Siehe dazu auch das folgende Kapitel.
database/script
035 SET DATABASE COLLATION "German"
036 CREATE SCHEMA PUBLIC AUTHORIZATION DBA
037 CREATE USER SA PASSWORD ""
038 GRANT DBA TO SA
039 SET WRITE_DELAY 60
In der script-Datei finden sich die Standardeinstellungen für die Verbindung zur Datenbank, zur benutzten Sprache usw. Hier erscheint auch der später erwähnte Benutzer «SA».
In einer mit Inhalt gefüllten Datenbank werden in dieser Datei die Grundlagen für die Tabellendefinitionen gespeichert:
040 SET DATABASE COLLATION "German"
041 CREATE SCHEMA PUBLIC AUTHORIZATION DBA
Die Tabellen werden definiert, bevor der Datenbanknutzer definiert wird. Zuerst werden die Tabellen mit ihren Feldern im Cache erstellt.
042 CREATE CACHED TABLE "Ware"
043 ("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL
044 PRIMARY KEY,"Ware" VARCHAR(50),"Preis" DECIMAL(8,2),"MWSt" TINYINT)
045 CREATE CACHED TABLE "Verkauf"
046 ("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL
047 PRIMARY KEY,"Anzahl" TINYINT,"Ware_ID" INTEGER,"Quittung_ID" INTEGER,
048 CONSTRAINT SYS_FK_59 FOREIGN KEY("Ware_ID") REFERENCES "Ware"("ID"))
049 CREATE CACHED TABLE "Quittung"
050 ("ID" INTEGER GENERATED BY DEFAULT AS IDENTITY(START WITH 0) NOT NULL
051 PRIMARY KEY,"Datum" DATE)
Anschließend werden noch Änderungen an den Tabellen vorgenommen, damit die Beziehungen («REFERENCES») stimmig sind
052 ALTER TABLE "Verkauf" ADD CONSTRAINT SYS_FK_76 FOREIGN KEY("Quittung_ID")
053 REFERENCES "Quittung"("ID")
054 SET TABLE "Ware" INDEX'608 20'
055 SET TABLE "Verkauf" INDEX'1872 1656 1872 12'
056 SET TABLE "Quittung" INDEX'2232 1'
Nach der Einstellung der Position des Indexes in der data-Datei (erscheint nur hier in der script-Datei, wird nie direkt in SQL eingegeben!) werden die automatisch hoch schreibenden Felder der Tabellen («AutoWert») so eingestellt, dass sie die nächsten Werte bei Neueingaben erstellen. So ist z.B. der letzte eingetragene Wert im Feld "ID" der Tabelle "Ware" die Nummer 19. Das automatische Hochschreiben beginnt also mit der Nummer 20.
057 ALTER TABLE "Ware" ALTER COLUMN "ID" RESTART WITH 20
058 ALTER TABLE "Verkauf" ALTER COLUMN "ID" RESTART WITH 12
059 ALTER TABLE "Quittung" ALTER COLUMN "ID" RESTART WITH 1
060 CREATE USER SA PASSWORD ""
061 GRANT DBA TO SA
062 SET WRITE_DELAY 60
Wenn, wie auf den folgenden Seiten beschrieben, die externe HSQLDB verwendet wird, kann eventuell ein weiteres Problem mit den *.odb-Dateien in Verbindung mit manchen LO-Versionen auftauchen. Wird eine externe HSQLDB genutzt, so ist der sicherste Weg der über das hsqldb.jar-Archiv, das mit LO mitgeliefert wird. Wird ein anderes Archiv verwendet, so kann das dazu führen, dass die internen Datenbanken plötzlich nicht mehr zugänglich sind. Dies liegt daran, dass LO Schwierigkeiten hat, zwischen interner und externer HSQLDB zu unterscheiden und Meldungen von einem Versionskonflikt produziert.
Es muss als externe Datenbank die mitgelieferte hsqldb.jar-Datei genutzt werden. Außerdem muss aus der *.odb-Datei das database-Verzeichnis extrahiert werden. Die Datei properties hat hier einen Eintrag, der in LO 3.3 zu dieser Fehlermeldung führt:
010 version=1.8.1
steht in Zeile 11.
Diese Zeile ist zu ändern auf
010 version=1.8.0
Danach ist das database-Verzeichnis wieder in das *.odb-Päckchen einzulesen und die interne Datenbank lässt sich auch wieder unter LO öffnen.
Wenn aus irgendwelchen Gründen wohl die Datenbankdatei geöffnet wird, aber kein Zugang mehr zu den Tabellen existiert, kann direkt über Extras → SQL der Befehl SHUTDOWN SCRIPT eingegeben werden. Anschließend wird die Datenbank geschlossen und neu gestartet. Das Ganze funktioniert aber nicht, wenn bereits ein «Error im Script-file» gemeldet wird.
Die Daten der Datenbank liegen in der *.odb-Datei im Unterverzeichnis «database». Hier gibt es eine Datei «data» und eine Datei «backup». Ist die Datei «data» defekt, so kann sie über die Datei «backup» wiederhergestellt werden. Hierzu muss die im Verzeichnis «database» liegende Datei «properties» bearbeitet werden. Hier gibt es eine Zeile «modified=no». Diese muss umgeschrieben werden zu «modified=yes». Das zeigt dem System an, dass die Datenbank nicht korrekt beendet wurde. Jetzt wird aus der komprimierten «backup»-Datei beim Neustart eine neue «data»-Datei erstellt.
Die interne HSQLDB unterscheidet sich erst einmal nicht von der externen Variante. Wenn, wie im Folgenden beschrieben, erst einmal nur der Zugriff auf die Datenbank nach außerhalb gelegt werden soll, dann ist keine Serverfunktion erforderlich. Hier reicht schlicht das Archiv, was in LO mitgeliefert wurde. Es liegt im LO-Pfad unter /program/classes/hsqldb.jar. Die Verwendung dieses Archivs ist die sicherste Variante, da dann keine Versionsprobleme auftauchen.
Die externe HSQLDB steht unter http://hsqldb.org/ zum Download frei zur Verfügung. Diese anderen Versionen sollten allerdings nur genutzt werden, wenn Klarheit darüber besteht, wie Versionsprobleme zwischen interner und externer Variante behoben werden können.
Der Datenbanktreiber muss, sofern er nicht in dem Pfad der Java-Runtime liegt, als ClassPath unter Extras – Optionen – Java hinzugefügt werden.
Die Verbindung zu der externen Datenbank erfolgt über JDBC. Die Datenbankdateien sollen in einem bestimmten Verzeichnis abgelegt werden. Dieses Verzeichnis kann beliebig gewählt werden. Es liegt in dem folgenden Beispiel im home-Ordner. Nicht angegeben ist hier der weitere Verzeichnisverlauf sowie der Name der Datenbank.
Wichtig, damit auch Daten in die Datenbank über die GUI geschrieben werden können, muss: ergänzend neben dem Datenbanknamen «;default_schema=true» stehen. Dies kann noch durch ein «;shutdown=true» ergänzt werden, damit die DB nach dem Schließen von LO heruntergefahren wird.
Also:
001 jdbc:hsqldb:file:/home/PfadZurDatenbank/Datenbankname;default_schema=true;
shutdown=true
In dem Ordner befinden sich die Dateien
Datenbankname.backup
Datenbankname.data
Datenbankname.properties
Datenbankname.script
Datenbankname.log
Weiter geht es mit der Angabe des Standardnutzers, sofern nichts an der HSQLDB-Konfiguration geändert wurde:
Damit ist die Verbindung erstellt und es kann auf die Datenbank zugegriffen werden.
Vorsicht
Wird eine externe Datenbank mit einer Version Hsqldb 2.* bearbeitet, so kann sie anschließend nicht mehr in eine interne Datenbank unter LibreOffice umgewandelt werden. Dies liegt an den zusätzlichen Funktionen, die in der Version 1.8.* noch nicht vorhanden sind. Dadurch endet der Aufruf mit der Version 1.8.* bereits beim Einlesen der Script-Datei der Datenbank.
Ebenso wenig kann eine externe Datenbank, die einmal mit einer Version der 2er-Reihe bearbeitet wurde, anschließend wieder mit der externen Version 1.8.* bearbeitet werden, die kompatibel zu LibreOffice ist.
Auch kann bei der Nutzung einer anderen Version in der externen Datenbank die Version der internen Datenbank überschrieben werden. Der Aufruf als interne Datenbank ist dann unmöglich.
Die Einbindung der externen Datei hsqldb.jar in den Class-Pfad kann bei unterschiedlichen Versionen dazu führen, dass interne Datenbanken anschließend nicht mehr zu öffnen sind. Base kommt mit den gleichlautenden Treibern nicht zurecht und will die externe Variante auch für die internen Datenbanken nutzen. Das geht beim ersten Öffnen noch gut. Beim zweiten Öffnen kommt dann aber die Meldung, dass die Datenbank nicht mehr zu öffnen ist, da sie mit einer neueren Version der HSQLDB geschrieben wurde.
Dem kann abgeholfen werden, indem für die externen Datenbanken die Datei hsqldb.jar nicht über den Class-Pfad in LO fest eingegeben wird, sondern stattdessen der Class-Pfad für die jeweilige Datenbankdatei über ein Makro geschrieben wird, wie auch hier (http://forum.openoffice.org/en/forum/viewtopic.php?f=40&t=61155) zu lesen ist.
001 SUB Start
002 Const cPath = "/home/robby/public_html/hsqldb_test/hsqldb.jar"
003 DIM oDataSource AS OBJECT
004 DIM oSettings AS OBJECT
005 DIM sURL AS STRING
006 sURL = ConvertToURL(cPath)
007 oDataSource = ThisComponent.DataSource
008 oSettings = oDataSource.Settings
009 oSettings.JavaDriverClassPath = sURL
010 END SUB
Hier wird die Datei «hsqldb.jar» unter Linux in dem o.g. Pfad abgelegt. Anschließend wird dieser Pfad der momentan geöffneten Datenbank als Treiberdatei zugewiesen.
Dieses Makro wird nach dem Öffnen der *.odb-Datei einmal aufgerufen. Es schreibt dann in die in der *.odb-Datei befindlichen Datei content.xml die entsprechende Verbindung zur Java-Klasse:
001 <db:data-source-settings>
002 <db:data-source-setting
003 db:data-source-setting-is-list="false"
004 db:data-source-setting-name="JavaDriverClass"
005 db:data-source-setting-type="string">
006 <db:data-source-setting-value>
007 org.hsqldb.jdbcDriver
008 </db:data-source-setting-value>
009 </db:data-source-setting>
010 <db:data-source-setting
011 db:data-source-setting-is-list="false"
012 db:data-source-setting-name="JavaDriverClassPath"
013 db:data-source-setting-type="string">
014 <db:data-source-setting-value>
015 file:///home/robby/public_html/hsqldb_test/hsqldb.jar
016 </db:data-source-setting-value>
017 </db:data-source-setting>
018 </db:data-source-settings>
Letztlich könnte also auch ohne das Makro ein entsprechender Pfad direkt in die content.xml der *.odb-Datei eingetragen werden. Nur ist dieser Weg für den Normalnutzer sicher nicht so komfortabel zu handhaben.
Die interne HSQL-Datenbank hat den Nachteil, dass die Abspeicherung der Daten innerhalb eines gepackten Archivs erfolgt. Erst mit dem Packen werden alle Daten festgeschrieben. Dies kann leichter zu Datenverlust führen als es bei der Arbeit mit einer externen Datenbank der Fall ist. Im folgenden werden die Schritte gezeigt, die notwendig sind, um den Umstieg einer bestehenden Datenbank vom *.odb-Päckchen zur externen Version in HSQL zu erreichen.
Aus einer Kopie der bestehenden Datenbank wird das Verzeichnis «database» extrahiert. Der Inhalt wird in das oben beschriebene frei wählbare Verzeichnis kopiert. Dabei sind die enthaltenen Dateien um den Datenbanknamen zu ergänzen:
Datenbankname.backup
Datenbankname.data
Datenbankname.properties
Datenbankname.script
Datenbankname.log
Jetzt muss noch die «content.xml» aus dem *.odb-Päckchen extrahiert werden. Hier sind mit einem einfachen Texteditor die folgenden Inhalte zu suchen, die leider in einer durchlaufenden Zeile stehen, es sei denn, man verwendet für diese Arbeit einen speziellen sog. XML-Editor:
001 <db:connection-data>
002 <db:connection-resource xlink:href="sdbc:embedded:hsqldb"/>
003 <db:login db:is-password-required="false"/>
004 </db:connection-data>
005 <db:driver-settings
006 db:system-driver-settings=""
007 db:base-dn=""
008 db:parameter-name-substitution="false"/>
Diese Zeilen sind mit der Verbindung zur externen Datenbank zu ersetzen, hier der Verbindung zu einer Datenbank mit dem Namen "medien", die jetzt im Verzeichnis «hsqldb_data» liegt.
001 <db:connection-data>
002 <db:connection-resource
003 xlink:href="jdbc:hsqldb:file:/home/robby/Dokumente/Datenbanken/hsqldb_data/
004 medien;default_schema=true;shutdown=true"/>
005 <db:login db:user-name="sa" db:is-password-required="false"/>
006 </db:connection-data>
007 <db:driver-settings
008 db:java-driver-class="org.hsqldb.jdbcDriver"/>
Falls, wie oben geschrieben, die Grundkonfiguration der HSQLDB nicht angetastet wurde, stimmt auch der Nutzername und die nicht erforderliche Passworteinstellung.
Nach Änderung des Codes muss die content.xml wieder in das *.odb-Päckchen eingepackt werden. Das Verzeichnis «database» ist in dem Päckchen jetzt überflüssig. Die Daten werden in Zukunft durch die externe Datenbank zur Verfügung gestellt.
Für die Mehrbenutzerfunktion muss die HSQLDB über einen Server zur Verfügung gestellt werden. Wie die Installation des Servers erfolgt, ist je nach Betriebssystem unterschiedlich. Für OpenSuSE war nur ein entsprechendes Paket herunter zu laden und der Server zentral über YAST zu starten (Runlevel-Einstellungen). Nutzer anderer Betriebssysteme und Linux-Varianten finden sicher geeignete Hinweise im Netz.
Im Heimatverzeichnis des Servers, unter SuSE /var/lib/hsqldb, befinden sich unter anderem ein Verzeichnis «data», in dem die Datenbank abzulegen ist, und eine Datei «server.properties», die den Zugang zu den (eventuell also auch mehreren) Datenbanken in diesem Verzeichnis regelt.
Die folgenden Zeilen geben den kompletten Inhalt dieser Datei auf dem Rechner wieder. Es wird darin der Zugang zu 2 Datenbanken geregelt, nämlich der ursprünglichen Standard‑Datenbank (die als neue Datenbank genutzt werden kann) als auch der Datenbank, die aus der *.odb‑Datei extrahiert wurde.
001 # Hsqldb Server cfg file.
002 # See the Advanced Topics chapter of the Hsqldb User Guide.
003
004 server.database.0 file:data/db0
005 server.dbname.0 firstdb
006 server.urlid.0 db0-url
007
008 server.database.1 file:data/medien
009 server.dbname.1 medien
010 server.urlid.1 medien-url
011
012 server.silent true
013 server.trace false
014
015 server.port 9001
016 server.no_system_exit true
Die Datenbank 0 wird mit dem Namen "firstdb" angesprochen, obwohl die einzelnen Dateien in dem Verzeichnis data mit "db0" beginnen. Die neue Datenbank wird als "Datenbank 1" hinzugefügt. Hier sind Datenbankname und Dateibeginn identisch.
Die beiden Datenbanken werden mit folgenden Zugängen angesprochen:
001 jdbc:hsqldb:hsql://localhost/firstdb;default_schema=true
username sa
password
001 jdbc:hsqldb:hsql://localhost/medien;default_schema=true
username sa
password
Die URL wurde hier bereits jeweils um den für den Schreibzugang über die grafische Benutzeroberfläche von LO erforderlichen Zusatz «;default_schema=true» ergänzt.
Wenn tatsächlich im Serverbetrieb gearbeitet werden soll, ist natürlich aus Sicherheitsgründen zu überlegen, ob die Datenbank nicht mit einem Passwort geschützt werden soll.
Nun erfolgt die Serververbindung über LO. Im Hauptfenster von Base wird Bearbeiten → Datenbank → Eigenschaften aufgesucht.