allegro-Fortbildung 7 Wichtige Dateien 7.3 Primärschlüssel und automatische Nummernvergabe Dies ist in erster Linie eine Lektion für Systemverwalter. Sie faßt Informationen zusammen, die in verschiedene Zusammenhänge gehören und deshalb im Systemhandbuch getrennt sind, die aber oft zusammen gebraucht werden. [Den ersten Entwurf zu dieser Lektion lieferte dankenswerterweise Frau Dr. Koczian, Augsburg] Als Nur-Anwender können Sie sich heute entspannen, Sie brauchen diese Dinge nicht zu wissen. Schaden kann's aber nicht. Ein einfacher und eindeutiger Suchbegriff für jeden Satz einer Datenbank ist immer nützlich und für bestimmte Arbeiten unentbehrlich. Das gilt für allegro genauso wie für jedes andere Datenbanksystem. Einen solchen Suchbegriff nennt man Primärschlüssel. Diese Lektion will folgende Fragen beantworten: -- Wozu werden Primärschlüssel speziell in einer allegro-Datenbank gebraucht? -- Was muß bei der Parametrierung geschehen, damit jeder Satz seinen Primärschlüssel bekommt? -- Wie kommt man zu geeigneten Schlüsseln, wenn die Daten nicht "von Natur aus" ein passendes Feld enthalten? -- Wie wird so ein Schlüssel dann bei der Katalogisierung eingegeben? Primärschlüssel Gebraucht werden Primärschlüssel in allegro-Datenbanken beim Einspeisen von Daten mit dem Programm UPDATE und genauso in a99 beim Einspeisen mit dem FLEX-Befehl "update". Will man neue Daten nicht ohne jede Rücksicht auf die vorhandenen einfach als neue Sätze einfügen, sondern Dubletten vermeiden oder auch vorhandene Datensätze gezielt verändern, muß das Programm wissen, wie alte (= schon vorhandene) und neue Datensätze zusammengehören. Als Primärschlüssel gilt bei UPDATE und update der erste Register- eintrag, der beim Speichern eines Datensatzes gebildet wird. Damit er dafür brauchbar ist, muß er eindeutig sein und er muß bei hierarchischen Sätzen aus dem Hauptsatz gebildet werden, nicht aus einem Untersatz. Er braucht nicht dem Inhalt einer bestimmten Kategorie zu entsprechen (z.B. #00) und auch nicht für alle Satzarten nach den gleichen Regeln konstruiert zu werden und im gleichen Register zu erscheinen. Beispielsweise bekommen die Bestell- und Exemplarsätze, die das Programm ORDER erzeugt, andere Primärschlüssel als die Titelsätze der gleichen Datenbank. Im Standardschema, mit Standard-Indexparametern, besteht aber der Primärschlüssel eines Titelsatzes aus dem Inhalt der Kategorie #00, evtl. umcodiert, im Register 9. Der erste Kopfbefehl lautet ak=zz+@ Dieser Befehl wird immer ausgeführt, egal, welche Kategorien im Satz belegt sind oder nicht; der Schlüssel wird also für jeden Satz bei der Sprungmarke #-@ gebildet. Dies ist dann zwingend, wenn aLF oder ORDER benutzt werden, aber es ist immer praktisch, so zu verfahren. Der einfachste Primärschlüssel besteht aus dem unveränderten, allenfalls umcodierten Inhalt einer bestimmten Kategorie, dann sieht der Abschnitt für seine Erzeugung so aus: #-@ !00 p"|9" #+# Hier wird #00 umcodiert, nicht weiter vorbehandelt und im Register 9 indexiert. Mehr zum Thema 'Primärschlüssel' im Systemhandbuch bei der Beschreibung des Programms UPDATE (Abschnitt 9.3, S. 158f oder online: h ac9). Dort ist auch ein etwas weniger schlichtes Beispiel vollständig ausgeführt. Zwei Dinge noch in aller Deutlichkeit: 1. es gibt nicht DEN Primärschlüssel, d.h. er steht nicht in einem dafür festgelegten Feld, und 2. ein Primärschlüssel braucht keine Nummer zu sein. In unterschiedlichen Situationen können unterschiedliche Schlüssel die Primärrolle übernehmen. Dazu sind "nur" die entsprechenden Eingriffe in die Indexparameter nötig. Beim FLEX-Befehl "update" kann auch mit dem Befehl "set pX" ad hoc irgendein geeigneter Schlüssel zum Primärschlüssel ernannt werden! (mehr: h xset eingeben) Automatische Nummernvergabe Jede eindeutige Nummer, die in jedem Datensatz auftritt, KANN bei Bedarf als Primärschlüssel dienen. Nicht alle Datensätze besitzen "von Natur aus" ein Datenfeld, dessen Inhalt immer vorhanden und eindeutig ist. Die interne Nummer eignet sich nicht, weil sie veränderlich ist (s. Lektion 2.3, Verknüpfungskon- zepte). Eine ISBN gibt es nicht immer und sie ist gelegentlich auch nicht eindeutig. Signaturen werden u.U. erst spät im Geschäftsgang vergeben, die Aufnahme soll aber vorher schon im Katalog stehen. Außerdem können auch sie sich ändern. Zugangsnummern können für mehrere Bücher gleich sein, z.B. für alle Bücher auf einer Rechnung. Es wäre also praktisch, eine garantiert eindeutige Nummer für den Satz zusätzlich zu erzeugen, und zwar per Programm. Relationale Datenbanken haben dafür verschiedene Mechanismen: "Auto-increment"-Felder, Generatoren u.ä. allegro benutzt zwei Befehle in der Konfigurationsdatei, mit denen sehr flexible Formen der Numerierung erreicht werden können; allerdings kann jeder einzelne Datensatz nur eine automatisch vergebene Nummer bekommen. cg Kategorie für automatische Nummernvergabe festlegen Hinter cg steht eine Kategorienummer, sonst nichts. Meist wird cg00 gesetzt, zwingend ist das nicht. Die Kategorienummer gibt an, in welcher Kategorie die Konstruktionsvorschrift für die automatische Nummernvergabe zu finden ist. Ohne den Befehl cg wird keine Nummer automatisch vergeben. ci Standardform der zu vergebenden Nummer Wenn es einen Befehl cg gibt, und wenn die in diesem Befehl genannte Kategorie in einem Satz nicht belegt ist, dann wird sie so belegt, wie ci es vorschreibt. Die Angabe hinter ci muß diese Form haben: Rabc?kABC Dabei bedeuten R Nummer eines Registers (1-9 bzw. ':' für 10, ';' für 11) abc Beliebige Zeichen vor der Nummer ?k Platzhalter für die Nummer, k ist eine Zahl ABC Beliebige Zeichen hinter der Nummer Bis auf Registernummer und Fragezeichen kann alles fehlen, insbesondere Zeichen hinter der Nummer sind selten sinnvoll. Im durch R gegebenen Register muß der Kategorieinhalt indexiert werden, ggf. mit Prä- und Postfix wie in ci angegeben. Dann wird im Augenblick des Speicherns der bisher größte Eintrag der gegebenen Form ermittelt, die Zahl darin um 1 erhöht und bei Bedarf mit führenden Nullen auf k Stellen aufgefüllt. Der so ermittelte Eintrag kommt in die durch cg angegebene Kategorie des aktuellen Satzes. Wenn die Nummern-Kategorie nicht schon belegt war, passiert dies auch beim Ändern eines Satzes, nicht nur bei einem neuen Satz! Achtung: die Konfigurationsdatei ist nicht für das Indexieren des neuen Schlüssels im richtigen Register zuständig, das muß in den Indexparametern separat festgelegt werden. Es ist Voraussetzung für die Eindeutigkeit der automatisch vergebenen Nummern. Nummernvergabe je nach Satztyp Wirklich flexibel wird dieses Verfahren aber erst durch die Möglichkeit, die durch cg vorgegebene Kategorie explizit zu belegen. Ein Eintrag, der kein Fragezeichen enthält, wird gespeichert, wie er ist, eine automatische Nummernvergabe findet in diesem Fall nicht statt. Beim Ändern von Sätzen ist das der Normalfall, weil die Nummer meistens schon da ist. Enthält die Kategorie aber ein Fragezeichen, dann wird der Inhalt als Numerierungsvorschrift nach dem folgenden Schema interpretiert (ganz ähnlich wie in ci): #xzy |R#nnfabc?kABC #xzy ist die in cg angegebene Kategorie (d.h. in der Konfiguration steht "cgxzi"). |R ist das Register, in dem die letzte passende Nummer gesucht und die neue indexiert werden soll. Wenn diese Angabe fehlt, wird das Register aus ci genommen. #nnf ist eine gültige Kategorie- nummer; wenn sie vorhanden ist, wird die neu vergebene Nummer nicht in #xzy, sondern in #nnf gespeichert. Achtung: dann fehlt #xzy im fertigen Satz und wird beim nächsten Ändern des Satzes zusätzlich erzeugt, wie in ci vorgegeben. Wenn das nicht gewünscht wird, muß es explizit verhindert werden (wie das geht, kommt weiter unten). Der Rest des Kategorie-Inhalts wird genau so verarbeitet wie oben beschrieben. Beispiel: In der Standardkonfiguration steht cg00 ci9a?5 D.h. wenn #00 beim Speichern nicht schon belegt ist, dann kommt der nächste Eintrag der Form "axxxxx" hinein, die Zahl xxxxx wird aus Register 9 ermittelt und die Kategorie dort indexiert. Letzteres muß, wie gesagt, in den Indexparametern geregelt sein. Bestimmte Satztypen können aber andere Nummern kriegen, so steht z.B. in einem Personenstammsatz im Augenblick des Speicherns #00 p?4 d.h. dieser Satz bekommt die nächste vierstellige Nummer mit dem Präfix p, diese Nummer wird aber ebenfalls in Register 9 indexiert, wie es die Indexparameter für die #00 vorschreiben. Erläutert wird die automatische Nummernvergabe im Systemhandbuch bei den Konfigurationsbefehlen (Abschnitt A.1.3, Sonstige Konfigurationsbefehle, S. 293, oder h aca-1). Es liegt im übrigen zwar nahe, die automatische Nummernvergabe für den Primärschlüssel zu nutzen, wenn ein solcher gebraucht wird. Zwingend ist es aber nicht. Wenn es so sein soll, dann muß der erste Schlüssel beim Abarbeiten der Indexparameter aus der automatisch vergebenen Nummer entstehen, siehe oben. Vorgaben für die Nummernvergabe in den einzelnen Satz bringen Für Sätze, deren ID-Nummer genau dem Schema aus ci entsprechen soll, ist gar nichts zu tun: die entsprechende Kategorie bleibt bei der Eingabe leer. Für alle anderen Sätze wäre es lästig und fehlerträchtig, jedesmal beispielsweise "p?4" in #00 schreiben zu müssen. Das Eintragen fester Texte in beliebige Kategorien läßt sich über die Abfrageliste oder in den Windows-Programmen über Eingabeformulare regeln: In der Abfrageliste bringt eine Zeile der Form xxf"Text"abc< den Text "abc" in die Kategorie xxf. Das "<" sorgt dafür, daß der Eintrag ohne <Enter> sofort übernommen wird, wenn die entsprechende Stelle in der Abfrageliste abgearbeitet wird. Der zuständige Abschnitt für einen Personenstammsatz würde also etwa so beginnen: -p Personenstammsatz 00 " Id.Nr.: "p?4< Ganz ähnlich im Eingabeformular: hier schreibt eine Zeile <xxfabc den Text "abc" in die Kategorie xxf, dank "<" wieder ohne Benutzereingriff. Für den Personenstammsatz also [Personenstammsatz] <00 p?4 Schließlich kann die ID-Nummern-Kategorie auch noch im Flex onput.flx belegt werden, oder auch im Hilfsabschnitt der Indexparameterdatei. Wenn es darum geht, eine nachträgliche ID-Nummernvergabe beim Ändern eines Datensatzes zu verhindern, dann eignen sich onput.flx und Hilfsabschnitt besser als Abfrageliste und Eingabeformular, die beide nicht unbedingt für jede Korrektur benutzt werden. Jetzt muß der Eintrag so aussehen (cg00 vorausgesetzt): #00 |9#75zabc?ixyz Der Witz dabei ist, daß #75z eine UNgültige Kategorie sein muß. Dann wird der Eintrag zwar erzeugt, aber nicht gespeichert, und #00 bleibt leer. Nötig ist das in erster Linie für Sätze, die ihre ID-Nummern anderswo haben als in der sonst dafür vorgesehenen Kategorie. Erklärt wird das Einsetzen fester Texte mittels Abfrageliste im Systemhandbuch (Abschnitt A.2, Abfrageliste, S. 296f oder h aca-2; hier auch das Verhindern einer Nummernvergabe); Eingabeformulare sind im gedruckten Handbuch nicht so ausführlich beschrieben wie im zuständigen Online-Hilfetext (h form). Zum Hilfsabschnitt in den Indexparametern s. Systemhandbuch, Abschnitt 10.2.8, Programmierte Validierungen (Eingabeprüfung). |