ODBC-Anfragefeld

Anforderung

Sind bei der Aufbereitung von Druckausgaben Informationen notwendig, die nicht im Druckdatenstrom selbst zu finden sind, können diese Informationen eventuell aus externen Quellen von print2forms beschafft werden. Eine Methode zur Informationsgewinnung ist die Anfrage von Datenbanken, auf die mit Schlüsselinformation, die im Druckdatenstrom gefunden wurde, zugegriffen wird.

Für diesen Zweck gibt es seit geraumer Zeit in den Formularen das ODBC-Anfragefeld. Das Verhalten dieses Feldes wurde ab dem p2fClient Build 5745 und dem p2fGate Build 3053 deutlich aufgewertet, indem jetzt auch ganze Tabellen als Antwort auf die SQL-Anfrage ausgewertet werden können, nicht nur einzelne Zeilen.

Realisierung

Die hier realisierte Änderung des Anfragefeldes besteht darin, jede einzelne Zeile einer Anwort auf eine SQL-Anfrage intern in eine Trefferliste einzutragen. Damit wird es dann möglich, die in print2forms bereits vorhandenen Mechanismen zur mehrfachen Anwendung von Feldern auf passende Druckdaten elegant zum Füllen von Tabellen zu nutzen.

Als erläuterndes Beispiel soll ein Druckdatenstrom (rechts abgebildet) betrachtet werden, der einen Suchbegriff - hier der Text SCSI - für den Datenbankzugriff und eine Reihe von Platzhaltern - hier die Texte Zeile 1 bis Zeile 10 enthält.

Ziel des Beispiels ist, aus der Datenbank alle Artikel, die mit dem Begriff SCSI etwas zu tun haben, zu extrahieren, und dann die zehn Platzhalter mit der in der Datenbank gefundenen Information zu ersetzen. All' das kann in einem entsprechenden Formular mit Hilfe eines ODBC-Anfragefeldes und zweier Textfelder (weil die gewünschte Ausgabe zweispaltig sein soll) erledigt werden.

Formular

Die beiden Textfelder stehen für zwei Tabellenspalten. In der ersten Tabellenspalte steht die Artikelnummer. Diese Nummer wird in der Schablone des Textfeldes aus dem Ergebnis des ODBC-Feldes Datenbank ausgelesen, und zwar das erste Element der Anwortzeile.

In der zweiten Tabellenspalte steht die Artikelbezeichnung. Dieser Text wird in der Schablone des Textfeldes ebenfalls aus dem Ergebnis des ODBC-Feldes Datenbank ausgelesen, und zwar jetzt das zweite Element der Anwortzeile.

Beide Textfelder sind von ihrer Feldauswahl her so definiert, dass sie mehrfach gefunden werden können. In diesem Beispiel werden sie beide zehnmal getriggert, weil unter Feldindex / Bedingung ein entsprechend grosser Suchbereich angegeben ist und in den Druckdaten dann auch Zeile 1 bis Zeile 10 gefunden werden.

Die Positionierung beider Textfelder erfolgt relativ zur Fundstelle lediglich mit einer horizontalen Verschiebung. Über die Differenz der Verschiebung wird der Abstand der beiden Tabellenspalten bestimmt. Der vertikale Abstand der einzelnen Tabellenzeilen, bleibt damit so, wie er durch die Druckdaten vorgegeben ist.

Das ODBC-Anfragefeld schliesslich beschafft die Daten aus der Datenbank. Der Inhalt der in der linksstehenden Abbildung gekürzt dargestellten SQL-Anfrage lautet vollständig:

SELECT Nummer, Bezeichnung
FROM Artikel
WHERE Bezeichnung LIKE '\Datenbank:1%'

Die Feldauswahl des ODBC-Feldes liest aus den Druckdaten den Suchbegriff für den Datenbankzugriff, in diesem Beispiel hier den Text SCSI, der an einer festen Position in den Druckdaten zu finden ist. Die Referenz \Datenbank:1 in der Schablone ist der Platzhalter, der durch den gefunden Text ersetzt wird. (Diese Referenz mit dem Backslash referenziert den gefundenen Text, während die Referenz mit der Tilde in den Textfeldern die Ergebnisse der Anfrage referenziert!) Die tatsächlich ausgeführte SQL-Anfrage lautet dann:

SELECT Nummer, Bezeichnung
FROM Artikel
WHERE Bezeichnung LIKE 'SCSI%'

Ablauf

Mit dem Aufruf dieses Formulars werden zuerst die Feldauswahlen der einzelnen Felder ausgewertet. Wie in dem nachfolgenden Auszug aus der Ablaufverfolgung des print2forms-Clients gut zu erkennen, wird für das ODBC-Anfragefeld der Suchbegriff SCSI gefunden, gefolgt von jeweils zwei Treffern - jeweils Artikelnummer und Artikelbezeichnung - für die zehn Zeilen.

…
0 2015…27  Request <PRC/MX$-FXO.XML>
6 2015…27  Access <PRC/MX$-FXO.XML> (2189)
6 2015…27  Access <OVL/HR12_SX.XML> (3451)
6 2015…27  Page 1 State 1
6 2015…27  Pattern 1 'Artikelnummer': '0101D10000' ' +(Zeile.*)'
6 2015…27  Pattern 2 'Artikelbezeichnung': '0101D10000' ' +(Zeile.*)'
6 2015…27  Pattern 3 'Datenbank': '0101590000' ' +([A-Z].*)'
6 2015…27  Match 3 'Datenbank' 01590000: \1='SCSI' 
6 2015…27  Match 1 'Artikelnummer' 01D10000: \1='Zeile 1' 
6 2015…27  Match 2 'Artikelbezeichnung' 01D10000: \1='Zeile 1' 
6 2015…27  Match 1 'Artikelnummer' 02490000: \1='Zeile 2' 
6 2015…27  Match 2 'Artikelbezeichnung' 02490000: \1='Zeile 2' 
6 2015…27  Match 1 'Artikelnummer' 02C10000: \1='Zeile 3' 
6 2015…27  Match 2 'Artikelbezeichnung' 02C10000: \1='Zeile 3' 
6 2015…27  Match 1 'Artikelnummer' 03390000: \1='Zeile 4' 
6 2015…27  Match 2 'Artikelbezeichnung' 03390000: \1='Zeile 4' 
6 2015…27  Match 1 'Artikelnummer' 03B10000: \1='Zeile 5' 
6 2015…27  Match 2 'Artikelbezeichnung' 03B10000: \1='Zeile 5' 
6 2015…27  Match 1 'Artikelnummer' 04290000: \1='Zeile 6' 
6 2015…27  Match 2 'Artikelbezeichnung' 04290000: \1='Zeile 6' 
6 2015…27  Match 1 'Artikelnummer' 04A10000: \1='Zeile 7' 
6 2015…27  Match 2 'Artikelbezeichnung' 04A10000: \1='Zeile 7' 
6 2015…27  Match 1 'Artikelnummer' 05190000: \1='Zeile 8' 
6 2015…27  Match 2 'Artikelbezeichnung' 05190000: \1='Zeile 8' 
6 2015…27  Match 1 'Artikelnummer' 05910000: \1='Zeile 9' 
6 2015…27  Match 2 'Artikelbezeichnung' 05910000: \1='Zeile 9' 
6 2015…27  Match 1 'Artikelnummer' 06090000: \1='Zeile 10' 
6 2015…27  Match 2 'Artikelbezeichnung' 06090000: \1='Zeile 10' 
6 2015…27  ODBC connect: 'Kabel GmbH MYSQL' (1)
6 2015…27  ODBC Request 'Datenbank': 'SELECT Nummer, Bezeichnung|FROM Artikel|WHERE Bezeichnung LIKE 'SCSI%'' (70)
6 2015…27  ODBC Response 'Datenbank': 'SCSI2|SCSI-Kabel 1 Drive 60 cm|' (31)
6 2015…27  ODBC Response 'Datenbank': 'SCSI3|SCSI-Kabel 2 Drive 75 cm|' (31)
6 2015…27  ODBC Response 'Datenbank': 'SCSI4|SCSI-Kabel 3 Drive 90 cm|' (31)
6 2015…27  ODBC Response 'Datenbank': 'SCSI5|SCSI-Kabel 4 Drive 100 cm|' (32)
6 2015…27  ODBC Response 'Datenbank': 'AS5050MM|SCSI 50/50 pol M/M|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS5050FF|SCSI 50/50 pol F/F|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS5025MM|SCSI 50/25 pol M/M|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS5025FF|SCSI 50/25 pol F/F|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS50MM|SCSI-II Kabel 2 m|' (25)
6 2015…27  ODBC Response 'Datenbank': 'AS50MMA|SCSI-II-A Kabel 2 m|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS50MMB|SCSI-II-B Kabel 2 m|' (28)
6 2015…27  ODBC Response 'Datenbank': 'AS5025|SCSI-II Systemkabel 2 m|' (31)
6 2015…27  ODBC Response 'Datenbank': 'AS6850P1|SCSI-III-P Kabel 1 m|' (30)
6 2015…27  ODBC Response 'Datenbank': 'AS6850P2|SCSI-III-P Kabel 2 m|' (30)
6 2015…27  Page 2 State 1
6 2015…27  Pattern 4 'Artikelnummer': '0101D10000' ' +(Zeile.*)'
6 2015…27  Pattern 5 'Artikelbezeichnung': '0101D10000' ' +(Zeile.*)'
6 2015…27  Pattern 6 'Datenbank': '0101590000' ' +([A-Z].*)'
6 2015…27  ODBC disconnect: 'Kabel GmbH MYSQL'
…

Anschliessend wird die Verbindung zur Datenbank über den ODBC-Konnektor Kabel GmbH MYSQL hergestellt und für die nachfolgende SQL-Anfrage offen gehalten. Als Antwort auf die Anfrage erfolgen insgesamt 14 Antworten, die in eine Trefferliste übernommen werden.

Anschliessend werden die beiden Textfelder abgearbeitet. Da jedes der Textfelder zehn Treffer hatte, werden diesen nun die ersten zehn Antworten der SQL-Anfrage zugeordnet. Die übrig bleibenden vier Antworten bleiben unberücksichtigt und werden nach der vollständigen Bearbeitung des Formulars automatisch gelöscht.

Wären weniger als zehn Antworten auf die SQL-Anfrage eingegangen, würden entsprechend weniger Treffer der Textfelder ausgefüllt - die gedruckte Liste wäre kürzer. Das Druckergebnis ist in der Abbildung links unten zu sehen:




Hinweise

  • Leider gibt es im Augenblick noch keinen einfachen Mechanismus, der die im Beispiel übrig bleibenden vier Antworten der SQL-Anfrage - beispielsweise auf der nächsten Seite - verarbeitet. Von daher eignet sich das gezeigte Vorgehen nur für Fälle, in denen die Menge an Antworten vorher bekannt ist.

    Das kann zwar im SQL durch die LIMIT-Klausel erzwungen werden, aber das Aufsetzen der SQL-Anfragen auf den Folgeseiten ist nicht so einfach. Wenn Sie so einen Fall brauchen, sprechen Sie uns an.