===== 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 (p2f) 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 ==== {{ print2forms:tips:0054-2.png?150}}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 (p2f) 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 ==== {{print2forms:tips:0054-1.png}} 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 (p2f)-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 6 2015…27 Access (2189) 6 2015…27 Access (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: \\ \\ {{print2forms:tips:0054-3.png?300 }}\\ \\ \\ ==== 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.