Zur Homepage www.HI-Tier.de Kurz & bündig
Home Nach oben Weiter
Öffentlicher Bereich für Entwickler

 

Verfahren

Eine Anwendung, die das HIT-Protokoll versteht, muss immer folgenden Ablauf berücksichtigen:

  1. Verbindungsaufbau per Socket
  2. "Hello"-Antwort(en) vom HitServer holen, dann weiter bei 5.
  3. Anfrage an HitServer senden
  4. Antwort(en) vom HitServer holen
  5. Maximale Fehlerschwere der Antworten ermitteln und darauf reagieren
  6. War letzte Anfrage die Abmeldung vom System, dann Verbindungsabbruch durch Schließen des Socket oder weiter bei 3. mit Neu-Anmeldung,
    sonst weiter bei 3. mit nächster Anfrage

Dazu gibt es neben dem knapp beschriebenen Protokollaufbau ein paar Programmierhilfen.

Vorhandene Systeme

Wir betreiben verschiedene Systeme, die unterschiedliche Datenbasen haben, aber dennoch den gleichen Funktionsumfang bieten.

bulletTestsystem
bulletProduktionssystem
bulletund weitere für Regional- bzw. Prämienstellen

Alle Systeme werden sowohl für das Herkunftssicherungs- und Informationssystem für Tiere (kurz HI-Tier oder HIT) als auch für die Zentrale InVeKoS-Datenbank (kurz ZI-Daten oder ZID) verwendet.

Alle Betriebe, die Tierbewegungen, Prüfberichte, Labortests, Zahlungsanspruchsübertragungen und vieles mehr melden, arbeiten mit dem Produktionssystem. Jedes Bundesland vergibt hierzu in Zentralstellen Betriebsnummern und eine dazugehörige PIN, um sich mit diesen Angaben in HIT/ZID anmelden zu können. Jemand, der sich in HIT anmelden kann, hat auch Zugang zu ZID und umgekehrt. Was der Benutzer letztendlich für Aktionen durchführen darf, liegt dann an der ihm zugeteilten Kompetenz, die in HIT und ZID größtenteils völlig unterschiedlich sind.

Im Testsystem sind bereits Betriebsnummern zu verschiedenen Betriebstypen vorgegeben, um eigene Programme testen zu können. Mehr zu den Anmeldedaten im Test findet sich hier.

Verbindungsaufbau

Sämtliche oben genannten Systeme sind unter folgenden IP- bzw. Host-Adressen via Socket-Verbindungen (BSD Sockets, Winsock)  zu erreichen:

Domain nameIP address
hitserver.hi-tier.de212.18.9.50
hitbackup.hi-tier.de194.94.221.1

Die numerische Angabe sollte nicht verwendet werden, da wir uns vorbehalten, diese zu ändern! Für Zugriffe durch Firewalls siehe dort.

Es gibt an allen Adressen bestimmte Port-Nummern, um auf bestimmte Systeme zugreifen zu können:

PortSystem
2222Produktionssystem, Zugang #1
2223Testsystem, Zugang #1
2224Wartungssystem, nur für Integrationstests der Länder
2225Produktionssystem, Zugang #2
2226Testsystem, Zugang #2
2227Produktionssystem, Zugang #3
2228Produktionssystem, Zugang #4
2229Produktionssystem, Zugang #5
2230Wartungssystem, Zugang #2

Für Meldungen bzw. Abfragen  in der ZID werden die gleichen Adressen und Ports verwendet!

Anmerkung: Teilweise werden in den Beispielen auf dieser Webseite und in den von uns angebotenen Programmen wie der HitBatch-Client auch private IP-Adressen verwendet. Diese müssen ggf. auf oben genannte Adressen umgestellt werden, sonst kann keine Verbindung aufgebaut werden!

Verfügbarkeit

Da bei Systemwartungen oder auch bei unerwarteten technischen Problemen einzelne Ports nicht ansprechbar sein können, sollten Anwendungen dringend die Möglichkeit vorsehen, automatisch andere Adressen und Ports (siehe Tabellen oben) zu nutzen, wenn ein oder gar mehrere Zugänge eines Systems nicht erreichbar sind!

Das gleiche gilt für den von uns zur Verfügung gestellten HitBatch-Client. In seiner INI-Datei müssen die Parameter PRIMARYSERVER, PRIMARYPORT, BACKUPSERVER und BACKUPPORT korrekt ausgefüllt sein. Für das Produktionssystem etwa so (hier für hitbatch.ini):

PRIMARYSERVER=hitserver.hi-tier.de
PRIMARYPORT=2222
BACKUPSERVER=hitbackup.hi-tier.de
BACKUPPORT=2222

Alternativ kann auch für beide Zugänge der Port 2225 angegeben werden. Für die Testzugänge gelten für beide Zugänge die Ports 2223 oder 2226. Die Hostadresse sollte -wie im Beispiel- für beide Zugänge unterschiedlich sein.

Empfohlene Vorgehensweise (hier für Produktionssystem):

Das Format einer Antwort vom HIT-Server bzgl. der "Hello"-Message wird unten beschrieben.

Firewalls, Proxies

Anwender, die direkt mit dem Internet verbunden sind, geben in ihrem Programm nur eine Adresse und den gewünschten Port an, um sich mit uns zu verbinden.

Anwender in Firmennetzwerken o.ä., die ein lokales Netzwerk hinter einer Firewall betreiben, müssen in der Firewall mindestens zwei Ports (einen für den Test-Zugang, einen für den Produktions-Zugang) freischalten lassen! Um eine hohe Verfügbarkeit zu gewährleisten, sollten dringend zwei Ports für den Test-Zugang und zwei für den Produktions-Zugang eingerichtet werden und die eigene Anwendung wie oben im Abschnitt "Verfügbarkeit" beschrieben konfiguriert werden. Etwa so:

ZugangLokales Netzwerk Internet
Produktion:lokale.firewall.adresse:1230»hitserver.hi-tier.de:2222
Produktion: lokale.firewall.adresse:1231» hitbackup.hi-tier.de:2222
Test: lokale.firewall.adresse:1240» hitserver.hi-tier.de:2223
Test: lokale.firewall.adresse:1241» hitbackup.hi-tier.de:2223

Im Beispiel sind die Portnummern im lokalen Netzwerk willkürlich und können vom Netzwerkadministrator vorgegeben werden. Diese Adressen und Portnummern müssen Sie dann in Ihrer Anwendung angeben. Mehr zu Proxies & Firewalls hier.

Da wir unser eigenes Protokoll für den Datenaustausch verwenden, das nicht mit HTTP kompatibel ist, kann kein Web-Proxy verwendet werden. telnet-Proxies wiederum können benutzt werden, wenn die Anwendung dies unterstützt. Unsere eigenen Programme (z.B. HitBatch) sind jedoch nicht dafür ausgelegt.

Neben Hardware-Firewalls in größeren LANs können Virenscanner und Software-Firewalls auf den eigenen Rechnern verhindern, dass sich Anwendungen mit den Servern verbinden können. Mehr dazu im nächsten Kapitel.

SSL-Verbindungen über separate Ports bieten wir nicht an, haben aber im HIT-Protokoll eine Verschlüsselung implementiert. Mehr dazu hier.

Testen einer Verbindung

Auch ohne eine Anwendung läßt sich vom eigenen Rechner aus testen, ob die HitServer erreichbar sind. In einer Console (unter Windows via Eingabeaufforderung, unter Unix & Co. in einer Shell) folgendes angeben:

telnet hitserver.hi-tier.de 2222

Nach dem erfolgreichen Verbindungsaufbau muss sich ein HIT-Server mit einer Hello-Nachricht melden:

=0:0/116::HitServer bereit. Version NNN, TT.MM.JJJJ HH-MM. Sie sind mit dem Prod
uktionssystem P1A_Quint verbunden (Server benutzt neue Betriebstabellen/NEWADS)
HI-Tierzeit TT.MM.JJJJ HH-MM-SSh Challenge -8536065718885552706

oder

=0:4/120:SYSTEM/*:HitServer momentan nicht verfügbar.

Ist kein Verbindungsaufbau möglich oder kommt keine oder eine andere Antwort, dann sind die Verbindungsdaten zu prüfen. Eventuell muss in einer Software-Firewall eine mögliche Sperre aufgehoben bzw. auf Nachfrage eine Verbindung explizit dauerhaft zugelassen werden.

Hinweis: Das Systemprogramm telnet erhält in der Regel seitens einer Software-Firewall die Erlaubnis, Verbindungen mit externen Rechnern aufzubauen. Man kann also nicht automatisch davon ausgehen, dass eine eigene Anwendung oder auch der HitBatch via java.exe auch Verbindungen aufbauen darf, nur weil telnet das darf!

Kommunikation mit HIT-Protokoll

Grundlegendes

Jede Anfrage- und Antwortzeile des HIT-Protokolls besteht immer aus vier Komponenten, die jeweils durch ein : getrennt sind.

Eine komplette Zeile wird grundsätzlich mit einem Wagenrücklauf (Carriage Return, kurz CR, ASCII 13) und Zeilenvorschub (Line Feed, kurz LF, ASCII 10), d.h. "\r\n", Konstante vbCrLf in VisualBasic etc., abgeschlossen und zum HitServer gesendet. Antworten kommen ebenfalls mit dieser Zeilenende-Kennung zurück.

Also: Komponente1:Komponente2:Komponente3:Komponente4<CRLF>.

Anfragen

Jeder Anfrage (ob Meldung oder Abfrage) liegt eine sogenannte Entität (Name der Datentabelle) zugrunde, auf die sie sich bezieht. Diese muss somit bei jeder Anfrage angegeben werden. Soll beispielsweise eine Geburt gemeldet werden, dann muss die Entität GEBURT (Großbuchstaben!) angegeben werden. Die Liste aller Entitäten findet sich hier (nur die, die ohne !, $ und # beginnen!). 

Jede Anfrage erwartet zudem Spaltennamen, die dem Server entweder anzeigen, welcher Wert in welcher Spalte gespeichert werden soll, oder aus welchen Spalten bei Abfragen Daten geliefert werden sollen. Beide Angaben (Entität und Spaltennamen) werden in Komponente3 in der Form Entität/Spalte(n) (beides durch einen / getrennt) angegeben. Welche Spalten für welche Entitäten zulässig sind, läßt sich durch einen Klick auf die gewünschte Entität auf dieser Seite nachlesen.

Jede Anfrage erfordert zudem eine Aktion, was auf die Entität angewandt werden soll. Neben Abfragen (Code R) gibt es mehrere Arten von Meldungsaktionen:

bulletDatensatz einfügen mit I (scheitert wenn Satz mit identischem PK schon vorhanden ist)
bulletDatensatz stornieren (als ungültig kennzeichnen) mit S 
bulletDatensatz aktualisieren mit U (dazu muss i.d.R. ein Satz mit identischem PK schon vorhanden ist)
bulletDatensatz ändern mit X (fügt noch nicht vorhandenen Satz ein, storniert ggf. schon vorhandenen Satz mit identischem PK)
bulletDatensatz bestätigen oder überprüfen mit C 

Es gibt keine Aktion zum Löschen von Datensätzen! Es ist somit immer nachvollziehbar, was früher mal gemeldet wurde, auch wenn es aus heutiger Sicht falsch ist (und storniert wurde).

Neben der Aktion wird auch angegeben, ob die Anfrage feldweise (Code F), satzweise (Code S) und blockweise (Code B) durchgeführt wird. Im folgenden werden nur satzweise Anfragen erläuert, so dass folgende Aktionen möglich sind: IS zum Einfügen, SS zum Stornieren, US zum Aktualisieren, XS zum Ändern und CS zum Bestätigen. Schließlich gibt es zu jeder Aktion sogenannte Subcodes, die das Verhalten einer Aktion selbst steuern. Bei Meldungen mit IS oder XS kann z.B. gesteuert werden, wie sich der Server bei unklaren Angaben verhalten soll: entweder er speichert die Meldung trotzdem oder antwortet mit einer Nachfrage, um dem Client die Entscheidung zu überlassen.

Die Aktion wird in Komponente2 angegeben.

Die Komponente1 gibt an, ob die Anfrage eine einzelne/letzte Anfrage ist oder in einem Block mit weiteren zu betrachten ist. Daran anschließend eine laufende Nummer. Da im folgenden nur satzweise Anfragen erläutert werden, beginnt Komponente1 immer mit einem *, gefolgt von einer Ganzzahl.

Bei Meldungen werden neben den Spalten (Teil von Komponente3) auch Daten in der selben Reihenfolge der Spalten angegeben. Bei Abfragen kann man in Form von Bedingungen angeben, welche Daten man aus einer Entität erhalten möchte. Beides (Daten oder Bedingungen) wird in Komponente4 angegeben.

Mehrere Subcodes, Spalten, Daten und Bedingungsketten werden jeweils durch ein Semikolon ; getrennt angegeben und geliefert. Daten, die u.a. eines der Sonderzeichen :, ; und % enthalten, müssen analog der URL-Codierung codiert bzw. beim Lesen von Antworten decodiert werden - mehr dazu hier.

Zusammengefasst:

allgemein Komponente1:Komponente2:Komponente3:Komponente4
Meldungen*Nr:Aktion:Entität/Spalten:Daten

mit Aktion IS, XS, SS, US, CS, ggf. mit Subcode.

Beispiel:

*2:XS:GEBURT/LOM;BNR15;GEB_DATR:DE 01 123 45678;01 234 567 8901;01.01.2008

Abfragen*Nr:RS:Entität/Spalten:Bedingung

mit Aktion RS, ggf. mit Subcode.

Beispiel:

*5:RS/C:GEBURT/LOM;BNR15;GEB_DATR:BNR15;EQ;01 234 567 8901

Antworten

Antworten auf Anfragen bestehen pro Anfrage aus 1..n Antwortzeilen.

Jede Antwortzeile liefert in Komponente1 die gleiche Nummer zurück, wie sie in der Anfrage angegeben wurde. So können Antworten den Anfragen zugeordnet werden. Beginnt die Antwortzeile mit dem Kennzeichen %, dann folgen weitere Antwortzeilen. Ist das Kennzeichen ein =, dann ist dies die letzte bzw. einzige Antwortzeile. Hinter der Anfragennummer folgen bei mehreren Antworten Unternummern, die durch ein + von der Anfragennummer getrennt sind.

Im Gegensatz zu Anfragen enthält Komponente2 eine Aussage über Erfolg bzw. Nicht-Erfolg der Anfrage. Sie besteht wie bei einer Anfrage aus zwei Teilen, die durch ein / getrennt sind. Der linke Teil ist die Fehlerschwere, die aussagt, ob eine Aktion erfolgreich war oder nicht. Rechts vom / steht der sogenannte Antwortcode, eine Art Konstante, die einen bestimmten Fehler beschreibt. Werden bei einer Abfrage Daten geliefert, dann erhält die Antwortzeile eine negative Fehlerschwere und der Antwortcode den Wert 0.

Komponente3 enthält wie bei einer Anfrage die Entität und durch ein / getrennt die in der Antwort betroffenen Spalten. Wird z.B. bei einer Geburtsmeldung, die aus mehreren Spalten besteht, das Geburtsdatum bemängelt, dann wird in einer Antwortzeile zur Entität auch nur das Geburtsdatum angegeben. Wird bei den Spalten nur ein * angegeben, dann bezieht sich die Antwort auf die gesamte Meldung und nicht nur auf eine bestimmte Spalte. In Komponente4 steht dann dazu passend die Fehlermeldung. Ist die Fehlerschwere aus Komponente2 negativ, dann stehen in Komponente4 die Daten in der Reihenfolge der Spalten, jeweils getrennt durch ein Semikolon ;.

Zusammengefaßt:

allgemein Komponente1:Komponente2:Komponente3:Komponente4
Antworten%Nr+1:Schwere/Antwortcode:Entität/Spalten:Text
%Nr+2:Schwere/Antwortcode:Entität/Spalten:Text
=Nr+3:Schwere/Antwortcode:Entität/Spalten:Text

oder nur

=Nr:Schwere/Antwortcode:Entität/Spalten:Text

Beispiel:

%5+1:-1/0:GEBURT/LOM;BNR15;GEB_DATR:DE 01 123 45678;01 234 567 8901;01.01.2008
=5+2:1/121:GEBURT:"Anzahl Datenzeilen - 1"

Man muss alle Antwortzeilen einer Anfrage auswerten und dessen maximale Fehlerschwere ermitteln. Ist diese größer 1, dann müssen die Fehlermeldungen dazu ausgewertet und darauf reagiert werden! Man darf sich nie darauf verlassen, dass alle Meldungen und Abfragen fehlerfrei abgesetzt werden können! Das schließt die "Hello"-Message nach dem Connect und die Anmeldung mit ein!

Tiefergehende Details rund um's HIT-Protokoll finden sich hier. Dazu gehören feldweise und blockweise Anfragen, Aufbau von Bedingungen für Abfragen, sogenannte Abfragefunktionen (die mit !, $ und # beginnen), die Beschreibung aller Subcodes zu Aktionen und vieles mehr.

Anmeldung und Abmeldung

Um Datenänderungen oder Abfragen durchführen zu können, muss man sich erst im System anmelden. Dazu wird die Entität LOGON mit folgenden Spalten verwendet:

*1:XS:LOGON/BNR15;PIN;MELD_WG:01 234 567 8901;123456;4

Ist in der darauffolgenden Antwort eine Fehlerschwere größer 1 vorhanden, dann ist die Anmeldung fehlgeschlagen. Eine erfolgreiche Anmeldung sieht so aus:

=1:0/223:LOGON/*:"Anmeldung erfolgreich."

Jetzt kann man im Rahmen der der Betriebsnummer zugeteilten Kompetenzen wie oben beschrieben Aktionen durchführen.

Abmelden funktioniert analog:

*9:XS:LOGOFF:

(Die Angabe von Feldnamen und Datenspalten entfällt hier, daher endet die Anfrage mit dem dritten :)

Nach der Abmeldung bleibt die Socket-Verbindung bestehen. Man kann sich daher unter einer anderen Betriebsnummer anmelden, ohne eine neue Verbindung aufbauen zu müssen. Wird keine weitere Anmeldung benötigt, sollte die Socket-Verbindung einfach geschlossen werden.

Programmierhilfen

Allgemeines

Zeichencodierung

HIT/ZID arbeitet mit dem Zeichensatz (Charset) ISO-8859-1.

Da im HIT-Protokoll bestimmte Zeichen nicht als Daten verwendet werden dürfen, schreibt man sich erst zwei Funktionen, die Text als Hex-Quoted und umgekehrt umsetzen. Also z.B. aus einem

20%iger NR-Anteil des ZA vorhanden; wird eingezogen

wird hex-quoted

20%25iger NR-Anteil des ZA vorhanden%3B wird eingezogen

und umgekehrt wieder

20%iger NR-Anteil des ZA vorhanden; wird eingezogen

Das Codieren könnte recht einfach so durchgeführt werden:

function textInHexQuoted(text)	{
   text = replace(text,"%","%25")	// muss als erstes ersetzt werden!
   text = replace(text,":","%3A")
   text = replace(text,";","%3B")
   // weitere Sonderzeichen wie Zeilenumbrüche, Tabulatoren etc
   // sollten auch ersetzt werden!

   return text
}

Decodieren ist da etwas schwieriger, da strenggenommen jede 2-stellige Hexadezimalzahl hinter dem % vorkommen kann. Viele Programmiersprachen bieten aber Methoden zum Übersetzen solcher Hex-Strings in Zahlen und weiter in Zeichen.

Unterscheidung zwischen "nicht vorhanden" und "leer"

In HIT/ZID gibt es viele Datenspalten, die keinen Wert enthalten, weil sie optional sind. Zusätzlich gibt es Zeichenkettenfelder, z.B. für Bemerkungen bei Prüfberichten, die leer sein dürfen.

Um nun eine leere Zeichenkette von einem nicht vorhandenen Wert unterscheiden zu können, wurde ein eigener Code eingeführt: %--.

Ein

*1:XS:GEBURT/...;TIERNAME;LOM:...;;DE 01 234 56789

schreibt eine leere Zeichenkette in das Feld TIERNAME, wohingegen ein

*1:XS:GEBURT/...;TIERNAME;LOM:...;%--;DE 01 234 56789

nichts in das Feld schreibt (für die, die SQL kennen: es wird null statt '' geschrieben). Umgekehrt werden Datenspalten bei Antworten, die Daten aus leeren Feldern liefern, ebenso mit %-- gefüllt.

Mehr Details dazu hier.

Anfragen

Eine Anfrage erwartet -wie oben beschrieben- vier Teile: eine Aktion, eine Entität, dazugehörige Spalten und dessen Daten bzw. bei Abfragen eine passende Bedingung. Das naheliegendste ist daher, eine Funktion zu schreiben, die diese vier Teile als Parameter übernimmt und daraus eine vollwertige HITP-Anfrage bastelt.

Etwa so (schematisch):

function baueAnfrage(aktion,entity,spalten,datenOderBedingung)	{
   return "*2:"+aktion+":"+entity+"/"+spalten+":"+datenOderBedingung
}

Da man technisch betrachtet zwischen Meldungen und Abfragen unterscheidet, kann man sich auch statt dessen zwei Funktionen schreiben. Für Meldungen kann dann ein Hash mit Schlüssel-Wert-Paaren (auch Dictionary, Map oder assoziatives Array genannt) verwendet werden, um sicherzustellen, dass die gleiche Anzahl Spalten wie Daten angegeben wird. Etwa so:

function baueMeldung(aktion,entity,hash)	{
   if aktion beginnt mit "R" then Fehlermeldung "Funktion baueAbfrage verwenden!"
   keys = leeres Array
   values = leeres Array
   for each eintrag in hash
      key aus eintrag holen
      key in hex-quoted umwandeln
      key an Array "keys" anhängen
      value aus eintrag holen
      value in hex-quoted umwandeln
      value an Array "values" anhängen
   next
   alle Elemente von "keys" mit ";" verknüpfen
   alle Elemente von "values" mit ";" verknüpfen
   return "*2:"+aktion+":"+entity+"/"+keys+":"+values
}

Für Abfragen dann etwa dies: 

function baueAbfrage(aktion,entity,spalten,bedingung)	{
   if aktion beginnt nicht mit "R" then Fehlermeldung "Funktion baueMeldung verwenden!"
   return "*2:"+aktion+":"+entity+"/"+spalten+":"+bedingung
}

Die laufende Nummer bei jeder Anfrage kann man automatisch hochzählen, muss man aber nicht. Sie kann wie im Beispiel statisch bleiben.

Die Zeichenkette, die eine der Funktionen liefert, wird schließlich um den Zeilenumbruch CRLF (s.o.) erweitert und an den HitServer gesendet. Danach wartet man auf die Antwort vom HitServer.

Antworten

Wie oben unter Grundlegendes bereits erwähnt, muss man zu einer Anfrage (egal ob Meldung oder Abfrage) immer alle Antworten lesen. Dies gilt auch für die "Hello"-Message direkt nach einem Verbindungsaufbau! Eine Leseroutine sollte daher vereinfacht folgendes tun:

function leseVonHit()	{
   antworten = leeres Array
   Schleife:
      Lese Zeile vom Socket
      Entferne ggf. CRLF am Ende
      Zeile in Array "antworten" merken
      if Zeile beginnt mit "=" then Schleife abbrechen
      Wiederhole Schleife
   return antworten
}

Das erhaltene Array der Antworten muss dann unbedingt ausgewertet werden. Da jedes Element dieses Arrays eine nahezu einheitliche Form besitzt, bietet es sich an, eine Funktion zu schreiben, die jede Antwortzeile in ihre Bestandteile zerlegt. Idealerweise legt man sich dazu auch eine Struktur, ein Objekt oder ein Hash für Schlüssel-Wert-Paaren (auch Dictionary, Map oder assoziatives Array genannt) an, in dem eine ganze Antwortzeile abgebildet wird. Hier exemplarisch als Struktur:

structure Antwort	{
   antwortnummer	// Integer
   unternummer		// Integer oder leer
   schwere		// Integer
   antwortcode		// Integer
   meldung		// String (=Entität)
   feldliste		// Array aus Strings oder leer
   datenliste		// Array aus Strings oder leer
}

Eine Antwortzeile wird dann gemäß der obigen Formatbeschreibung einer Antwort etwa wie folgt in seine Bestandteile zerlegt:

function zerlegeAntwort(zeile)	{
   antwort = neue Struktur o.ä. anlegen

   Zerlege zeile in maximal 4 Komponenten anhand ":"

   Extrahiere antwortnummer und ggf. unternummer aus komponente1
   Beide Teile als antwortnummer und unternummer in "antwort" speichern

   Zerlege komponente2 in maximal 2 Teile anhand "/"
   Beide Teile als schwere und antwortcode in "antwort" speichern

   Zerlege komponente3 in maximal 2 Teile anhand "/"
   Teil1 als meldung in "antwort" speichern
   if Teil2 ist nicht leer then
      Zerlege Teil2 anhand ";" in einzelne Spalten
      Spalten als feldliste in "antwort" speichern
   end if

   Zerlege komponente4 anhand ";" in einzelne Daten
   Schleife über alle Daten
      Datenspalte aus hex-quoted in Text umwandeln
      Entferne rechts und links die beiden Hochkommas, wenn vorhanden
      Wiederhole Schleife
   Daten als datenliste in "antwort" speichern

   return antwort
}

Wichtig: Die beschriebene Struktur Antwort und auch die Zerlege-Funktion beschreiben nur das wesentliche einer Antwort! Es gibt an der ein oder anderen Stelle noch weitere Unterteilungen oder Sonderfälle, die ggf. zu berücksichtigen sind. Mehr dazu hier. Nichtsdestotrotz sollte der Pseudocode in der Form funktionieren.

Das Lesen der Antworten von HIT und Zerlegen dieser kann natürlich auf einmal geschehen. Dazu einfach oben in der Leseroutine das dunkelrot markierte durch folgendes ersetzen:

      antwort = zerlegeAntwort(Zeile)
      antwort in Array "antworten" merken

Hat man alle erhaltenen Antworten zu einer Anfrage gelesen und zerlegt, muss die maximale Schwere aller Antworten ermittelt werden. Etwa so:

function liefereSchwere(antworten)	{
   maximaleSchwere = -999

   Schleife über alle antworten
      if schwere aus antwort > maximaleSchwere then
         maximaleSchwere = schwere aus antwort
      end if
      Wiederhole Schleife

   return maximaleSchwere
}

Je nach maximaler Schwere muss reagiert werden:
bulletBei Schwere = 1 oder kleiner wurden Datenänderungen akzeptiert oder es konnte eine Datenabfrage durchgeführt werden.
bulletBei Schwere = 2 ist die zuvor gesendete Anfrage nicht akzeptiert worden (es wurden keine Daten geändert), aber man kann die Anfrage erneut senden, jedoch die Aktion um den Subcode T erweitert, um die Daten dennoch zu ändern. Ob die Anfrage erneut gesendet werden soll, kann man entweder automatisch oder interaktiv steuern.
bulletBei Schwere 3 oder größer war die zuvor gesendete Anfrage fehlerhaft. Durch logische Zusammenhänge anhand von internen Prüfungen kann eine Änderung unterbunden werden. Es kann auch strukturell bedingt sein, wenn z.B. eine Abfragebedingung fehlerhaft ist, weil Operatoren falsch angewandt wurden.

Um bei einer Datenabfrage (Aktion RS) und maximaler Schwere kleiner 2 die Kopfzeile und nachfolgende Datenspalten zu erhalten, geht man wie folgt vor:

   datenzeilen = leeres Array
   Schleife über alle antworten
      if Antwort mit Schwere >= 0 then Wiederhole Schleife
      if Array "datenzeilen" ist leer then
         kopfzeile = feldliste
      end if
      datenliste aus "antwort" an Array "datenzeilen" anhängen
      Wiederhole Schleife

Bei Abfragen werden Kopfzeilen im HIT-Protokoll nur bei der ersten Antwort ausgeben und bei den nachfolgenden zur Abfrage gehörenden Antworten weggelassen, um die Datenübertragung zu beschleunigen. Daher wird im Codestück die kopfzeile nur von der ersten Antwort abgegriffen.

Weitere Hilfen

Um Funktionalitäten der Weboberflächen nachbilden zu können, kann man sich (nach Anmeldung) den sogenannten HitCache anzeigen lassen. Dieser zeigt die beim Arbeiten in der Webanwendung bisher abgesetzten HIT-Protokoll-Anfragen an.

Die Seite ist im HIT zu erreichen unter:

HIT-Menü

> Rinderdatenbank - Abfragen: weitere Abfragen und Funktionen ...

> Anzeige der zuletzt ausgeführten internen Befehle (HITP)

In ZID gibt es das Pendant unter:

ZID-Menü

> Anzeige der zuletzt ausgeführten internen Befehle (HITP)


© 1999-2015 Bay.StMELF, verantwortlich für die Durchführung sind die Stellen der Länder , fachliche Leitung ZDB: Frau Dr. Kaja.Kokott@hi-tier.de, Technik: Helmut.Hartmann@hi-tier.de
Seite zuletzt bearbeitet: 29. September 2016 15:38, Anbieterinformation siehe hier im Impressum.