SQL Zugriff auf Systemdatenbank

Hey!

In diesem Tutorial zeige ich euch, wie ihr mit Hilfe von SQL Befehlen Daten aus der Systemgeberdatenbank holen könnt. Wenn man die Datenbank Abfragen möchte, muss man eine MS-Access-SQL Abfrage an das KKP schicken. Das Ergebnis dieser Abfrage wird dann in eine XML Struktur gespeichert und als XML-String zurückgegeben. Ein einfaches Skript sieht so aus:

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
if __name__ == ‚__main__‘:
    sQuery = „HIER KOMMT DIE ABFRAGE HIN“
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 1:
        sXml = erg[1]
        kkp.MsgBox(sXml[0:1000])

Nun wäre es gut, wenn wir zunächst einmal herausfinden könnten, welche Tabellen wir in unserer Datenbank haben. Auf Grund der Sicherheitseinstellungen und des zugrunde liegenden Datenbankensystems verwenden wir hier eine spezielle Sonderfunktion, die über eine spezielle Sonderabfrage aufgerufen wird.

Als Query geben wir einfach nur den Begriff „tables“ ein. Dadurch wird das KKP angewiesen eine Auflistung aller verfügbaren Tabellen und deren Spalten herauszurücken.

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
if __name__ == ‚__main__‘:
    sQuery = „tables“
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 1:
        sXml = erg[1]
        kkp.MsgBox(sXml[0:1000])

In meinem System sieht das Ergebnis (nur die ersten tausend Zeichen) so aus. Da jeder Systemgeber aber spezielle Anforderungen hat, sieht die Datenbank bei jedem Systemgeber anders aus. Also, die Abfragen, die ich in diesem Beispiel zeigen werden, können so nicht unbedingt bei einem anderen Systemgeber verwendet werden. Da müssen die Abfragen entsprechend auf die Struktur der Datenbank angepasst werden. Daher ist es auch sehr wichtig, die Tabellen und darin enthaltenden Spalten zu kennen.

Nun legen wird diesen XML String mal in ein XML Objekt, damit wir die reinen Tabellennamen auflisten können.

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
import xml.etree.ElementTree as ET
def tabellenNamenAuflisten(xml):
    for xmlTable in xml.findall(‚table‘):
        sTableName = xmlTable.get(„name“)
        print(sTableName)
if __name__ == ‚__main__‘:
    sQuery = „tables“
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 1:
        sXml = erg[1]
        xml = ET.fromstring(sXml)
        tabellenNamenAuflisten(xml)

Damit können wir uns dann ja nun eine Funktion bauen, mit der wir gezielt die Spalten für eine Tabelle bekommen. Ich möchte nämlich wissen, welche Spalten die Tabelle „Artikel“ beinhaltet.

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
import xml.etree.ElementTree as ET
def tabellenNamenAuflisten(xml):
    tabellenNamen = []
    for xmlTable in xml.findall(‚table‘):
        sTableName = xmlTable.get(„name“)
        tabellenNamen.append(sTableName)
    return tabellenNamen
def getSpaltenFuerTabelle(xml , name):
    spalten = []
    for xmlTable in xml.findall(‚table‘):
        sTableName = xmlTable.get(„name“)
        if sTableName == name:
            for xmlSpalte in xmlTable.findall(‚record‘):
                sName = xmlSpalte.get(’name‘)
                spalten.append(sName)
    return spalten
if __name__ == ‚__main__‘:
    sQuery = „tables“
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 1:
        sXml = erg[1]
        xml = ET.fromstring(sXml)
        tabellenNamenAuflisten(xml)
        spaltenNamen = getSpaltenFuerTabelle(xml , „Artikel“)
        print(spaltenNamen)

Leider beinhaltet meine Datenbank keine Artikel. Aber das macht nichts. Denn wir können ja auch andere Tabellen abfragen. Ich habe die Tabelle Farben gesehen. Holen wir uns doch einfach mal die Spalten aus dieser Tabelle. Dazu müssen wir unserem Skript nur den Tabellennamen „Artikel“ durch „Farben“ ersetzen.

In der Farben-Tabelle haben wir die Spalten ID, Sortierung, Farbnr, Name1, Name2, Rot, Gruen, Blau

Diese Spalten möchte ich gerne abfragen. Dazu baue ich mir aber ein neuen Skript.

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
import xml.etree.ElementTree as ET
def query(sQuery):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 0: xml = ET.fromstring(erg[1])
    else: xml = None
    return xml
def FarbenAuflisten():
    xml = query(„Select ID, Sortierung, Farbnr, Name1, Name2, Rot, Gruen, Blau from Farben“)
if __name__ == ‚__main__‘:
    FarbenAuflisten()

in xml steht nun der gesamte Inhalt als XML.

Die XML hat folgenden Aufbau

<XML>

<record ID=““ Sortierung=““ …/>

</XML>

Wir können also einfach die xml nach records durchlaufen lassen und den jeweiligen Spaltennamen als Attribut abfragen.

def FarbenAuflisten():
    xml = query(„Select ID, Sortierung, Farbnr, Name1, Name2, Rot, Gruen, Blau from Farben“)
    for xmlRecord in xml.findall(‚record‘):
        id = xmlRecord.get(‚ID‘)
        sortierung = xmlRecord.get(‚Sortierung‘)
        farbnr = xmlRecord.get(‚Farbnr‘)
        name1 = xmlRecord.get(‚Name1‘)
        …

Wenn wir dann eine Ausgabe machen, werden wir festellen, dass wir so viele Daten haben, dass das KKP diese nicht am Stück anzeigen möchte. Aber wenn ich nur „Name1“ ausgebe, klappt das mit meiner Datenbank so gerade eben noch.

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
import xml.etree.ElementTree as ET
def query(sQuery):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 0: xml = ET.fromstring(erg[1])
    else: xml = None
    return xml
def FarbenAuflisten():
    xml = query(„Select ID, Sortierung, Farbnr, Name1, Name2, Rot, Gruen, Blau from Farben“)
    for xmlRecord in xml.findall(‚record‘):
        id = xmlRecord.get(‚ID‘)
        sortierung = xmlRecord.get(‚Sortierung‘)
        farbnr = xmlRecord.get(‚Farbnr‘)
        name1 = xmlRecord.get(‚Name1‘)
        print(name1)
if __name__ == ‚__main__‘:
    FarbenAuflisten()

Du siehst aber schon, dass ich auch den Screenshot vom Ausgabefenster abschneiden musste, weil da einfach so viele Daten drin sind.

Aber so können wir nun, genau wie mit jeder anderen Datenbank auch gezielte Abfragen machen. Ich sehe in meinem Screenshot, dass wir eine Farbe haben, die „Beige“ heißt. Dann erstelle ich mir mal eine Abfrage, nur nach der Farbe „Beige“

# -*- coding: utf-8 -*-
import kkp
import kkp_gemeinsame
import ole
import xml.etree.ElementTree as ET
def query(sQuery):
    erg = kkp.OLE_CMD(ole.OLE_QUERY_SYSTEMGEBER_DATENBANK , sQuery)
    if len(erg) > 0: xml = ET.fromstring(erg[1])
    else: xml = None
    return xml
def FarbenAuflisten():
    xml = query(„Select ID, Sortierung, Farbnr, Name1, Name2, Rot, Gruen, Blau from Farben where Name1 = ‚Beige'“)
    for xmlRecord in xml.findall(‚record‘):
        id = xmlRecord.get(‚ID‘)
        sortierung = xmlRecord.get(‚Sortierung‘)
        farbnr = xmlRecord.get(‚Farbnr‘)
        name1 = xmlRecord.get(‚Name1‘)
        name2 = xmlRecord.get(‚Name2‘)
        r = xmlRecord.get(‚Rot‘)
        g = xmlRecord.get(‚Gruen‘)
        b = xmlRecord.get(‚Blau‘)
        print(id + „, “ + sortierung + „, “ + farbnr + „, “ + name1 + „, “ + name2 + „, “ + r + „, “ + g + „, “ + b)
if __name__ == ‚__main__‘:
    FarbenAuflisten()

Diese Information(en) könnte ich nun verwenden um zum Beispiel eine UI Maske mit allen verfügbaren Farben zu befüllen. Oder ich könnte auch eine Liste mit Zubehörartikeln erstellen. Ich könnte mir aber auch heraussuchen, welche Artikel eine bestimmte Lagerlänge besitzen oder welche Gläser in der Datenbank eingerichtet sind. Genauso könnte ich nun auch die Preise für meine Artikel ermitteln und an ein ERP System schicken. Die Möglichkeiten sind hier fast grenzenlos.