XML-Import-Schnittstelle
XML Import-Schnittstelle
Schema XML-Import
Voraussetzung
In der Datei
\client\jboss\custom\configuration.batmuss der ParameterSET XML_IMPORT_DIR=gesetzt werden. (z.B.SET XML_IMPORT_DIR=c:\Temp\xmlimport\ueberwacht)Das Modul CURSOR-Webservice muss lizenziert sein.
Damit die Überwachung gestartet wird, muss das Verzeichnis existieren. Außerdem muss in diesem Verzeichnis ein Unterverzeichnis mit dem Windows-Benutzerkürzel des Anwenders existieren. Ist dies nicht vorhanden, wird die Überwachung des Verzeichnisses nicht gestartet
Start des Imports
Beim Start der Anwendung wird der Importer gestartet, wenn Folgendes erfüllt ist:
Der Parameter
XML_IMPORT_DIRist gesetztDas angegebene Verzeichnis existiert
Es existiert ein Unterverzeichnis mit dem Kürzel des angemeldeten Benutzers (Windows-Benutzername)
Es existiert keine Datei lock.txt im Unterverzeichnis mit dem Benutzerkürzel
Sind diese Vorraussetzungen erfüllt, wird die Überwachung des Import-Verzeichnisses gestartet.
Die Datei 'lock.txt'
Die Datei lock.txt stellt sicher, dass nur ein Client auf dem Rechner den Import starten kann. Wenn die Datei gelöscht wird, so wird die Import-Überwachung automatisch gestoppt.
Ist die Datei beim Start der Anwendung älter als 24 Stunden, so wird die Datei gelöscht und der Import gestartet.
Beim normalen Beenden der Anwendung wird die Datei gelöscht. Sollte die Datei z. B. durch einen Programmabsturz nicht gelöscht worden sein, kann sie manuell gelöscht werden, damit die Überwachung beim nächsten Start wieder gestartet wird.
Ablauf des Imports
Alle 10 Sekunden wird geprüft, ob neue Dateien mit der Endung xml vorhanden sind. Diese Zeit ist über einen PropertyMapper-Eintrag konfigurierbar:
INSERT INTO PropertyMapper (Pk, id, property, PropertyType, principal, PropertyValue, CustLayer, Active, CreateDate, CreateUser, UpdateDate, UpdateUser, STATUS, RightPk, ClientNo, MassData)
VALUES ('SYSTEM.XMLImporter.ImportPeriod', '/de/cursor/jevi/client/swingclient/importer/SchemaXMLImporter$!!$ImportPeriod', '' ,'SYSTEM', '', '30000', 'CN' 1,
GETDATE(), 'TECH_USER', GETDATE(), 'TECH_USER', NULL, NULL, NULL, 0)
Die Zeit wird in Millisekunden angegeben, die '30000' steht also für 30 Sekunden. Der Eintrag kann auch aktualisiert werden:
UPDATE propertymapper SET propertyvalue = '50000' WHERE pk = 'SYSTEM.XMLImporter.ImportPeriod'
Es wird als erstes geprüft, ob es sich um eine Datei für den bisherigen XML-Import, oder um eine Datei für den Import mittels Schema handelt. Ist ein Tag Config mit den gefüllten Attributen version und testRun vorhanden, so handelt es sich um den Schema Import. Ist dies nicht der Fall, wird die Datei in das Unterverzeichnis failure verschoben.
Dann wird der Import gestartet.
War der Import erfolgreich, so wird die XML-Datei in das Verzeichnis success verschoben. Das vom Import zurückgeliefert Ergebnis wird zusätzlich in das success-Verzeichnis verschoben. Die Datei hat den selben Namen wie die importierte Datei, nur ist hier der Zusatz _Result hinzugefügt. Existiert im success-Verzeichnis die zu verschiebende Datei, so wird das aktuelle Datum in Millisekunden (System.currentTimeMillis) an den Dateinamen angehängt, um den Dateinamen eindeutig zu machen.
War der Import nicht erfolgreich, wird die XML-Datei in das Verzeichnis failure verschoben. Gab es beim Import eine XMLImportException, so werden die zurückgelieferten Einträge auch in das Verzeichnis failure verschoben (mit der angehängten Endung _Result). Auch hier gilt, existiert die Datei schon im failure-Verzeichnis, werden die Millisekunden des aktuellen Datums angefügt.
Struktur
Eingabe
Tags und deren Attribute zur Eingabe
Tags | Attribute | Defaultwert | Mögliche Werte | Ab Version |
|---|---|---|---|---|
Entries | - | - | - | |
Config | transactionTime | Wert muss gesetzt werden | Zeit in Sekunden die eine Transaktion dauern darf | |
version | Wert muss gesetzt werden | Die Version der Anwendung in die importiert werden soll | ||
testRun | Wert muss gesetzt werden | true, false | ||
Entry | entity | Wert muss gesetzt werden | Alle existenten Entitäten | |
action | Wert muss gesetzt werden | CREATE - Datensatz anlegen | ||
found | Wert muss gesetzt werden | ZERO - Kein Datensatz gefunden | ||
relation | Leerstring | Die passende Relation zwischen dem aktuellen und dem übergeordneten Entry | ||
rightTemplate | Leerstring | Die zu setzende Rechtevorlage. Dies funktioniert nur bei Neuanlage, nicht beim Update. Die Vorlage muss vom Typ Satzrecht sein. Die Entität muss rechtebehaftet sein. | ||
Field | name | Muss gesetzt werden | Der Attribute-Name des zu bearbeitenden Feldes | |
fieldType | VALUE | PK - Der Wert ist ein Primärschlüssel | ||
identifyingField | false | true, false | ||
clearUnknown | false | true, false | 13.2 | |
function | IS_EQUAL | IS_EMPTY - ist leer | 13.2 | |
EntityLookupField | name | Muss gesetzt werden | Der Attribute-Name des zu bearbeitenden Feldes | |
identifyingField | false | true, false | 11.2 | |
Link | pk | Muss gesetzt werden | Der Pk des Datensatzes der verlinkt werden soll | |
entity | Muss gesetzt werden | Die Entität des Datensatzes der verlinkt werden soll | ||
relation | Muss gesetzt werden | Die passende Relation zwischen dem zu verlinkenden und dem aktuellen Entry |
Entries
Das 'Entries'-Tag ist das Grundelement der XML-Struktur. Es enthält bei der Eingabe keinerlei Attribute.
Entry
Für jeden zu bearbeitenden Datensatz muss das Entry-Tag verwendet werden.
entity enthält die Entität des Datensatzes.
action enthält die auszuführende Aktion.
found bestimmt bei wie vielen gefundenen Daten eine Aktion ausgeführt werden soll.
rightTemplate kann eine Rechtevorlage auf den Datensatz heften. Dies funktioniert nur bei Neuanlage, nicht beim Update. Die Vorlage muss vom Typ Satzrecht sein. Die Entität muss rechtebehaftet sein
relation wird gesetzt je nachdem ob das Entry-Tag geschachtelt oder auf Hauptebene verwendet wird und enthält die Relation zwischen den beiden Datensätzen.
<Entry entity="Customer" action="CREATE" found="ZERO" rightTemplate="MSG-Dateien">
...
</Entry>
<Entry entity="Customer" action="CREATE" found="ZERO">
...
<Entry entity="Customer" action="DELETE_LINK" found="ONE" relation="rCuCu">
...
</Entry>
</Entry>
Config
Das Config Tag dient der Konfiguration des Aufrufs, ist vorgeschrieben und sieht immer gleich aus. Es ist das erste Element in jeder Datei bzw. jedem Aufruf.
transactionTime legt fest wie lange der Aufruf maximal dauern darf bevor zurückgerollt wird.
version sollte die Version der Anwendung enthalten, für die der Aufruf geschrieben wurde. So kann festgestellt werden ob die Anwendung zum Aufruf kompatibel ist.
testRun schaltet zwischen dem Test-Modus und dem tatsächlichen Import um. Der Test-Modus simuliert alle Vorgänge des Imports und rollt am Ende die Transaktion wieder zurück. Der Benutzer erhält Informationen wie der Import verlaufen wäre.
<Config transactionTime="300" version="9.2" testRun="false"/>
Der Parameter transactionTime definiert, wie lange der Import-Vorgang (in Sekunden) dauern soll. Maximal kann ein Import 24 Stunden dauern. (transactionTime = 86400)
Field
Alle Werte werden in 'Field'-Tags angegeben.
name enthält den Attribute-Namen des zu setzenden Feldes.
identifyingField legt fest ob bei der Suche nach bestehenden Daten dieses Feld mit einbezogen wird. Große Textfelder, wie z.B. der Aktivitätentext, dürfen nicht als identifizierend markiert werden.
fieldType kann im Fall eines Nachschlagefeldes festlegen, dass der Schlüssel nicht validiert wird. In diesem Fall müsste statt dem Schlüssel direkt der Pk des Schlüssel angegeben werden.
clearUnknown kann im Fall eines Nachschlagefeldes festlegen, dass der Leerschlüssel eingetragen wird, wenn auf dem Feld der Leerschlüssel erlaubt ist und der Nachschlagewert nicht gefunden wird.
function gibt an wie nach den identifizierenden Feldern gesucht wird. Standardmäßig wird nach dem angegebenen Wert mit Gleichheit gesucht. Es ist aber möglich anzugeben, dass er nur enthalten, größer oder klein sein muss etc. Es darf nicht auf jedem Feldtyp jede Funktion gesetzt werden. Siehe dazu in der Tabele unten.
<Field name="FirstName.ContactPerson" identifyingField="true" function="STARTS_WITH">
<FieldValue>
<stringValue>Cornelia</stringValue>
</FieldValue>
</Field>
<Field name="DelegatedBy.Activity" identifyingField="false" fieldType="PK">
<FieldValue>
<stringValue>ged-personpk34#employee19</stringValue>
</FieldValue>
</Field>
<Field name="Priority.Activity" clearUnknown="true">
<FieldValue>
<stringValue>UNKNOWNKEY</stringValue>
</FieldValue>
</Field>
Je nachdem was das Feld für einen Datentyp hat, müssen Unterschiedliche Tags verwendet werden:
Datum: <dateValue>2008-04-20</dateValue> oder <dateTimeValue>2008-04-20T17:00:00</dateTimeValue>
Text: <stringValue>mein Text</stringValue>
Nachschlagefeld: <stringValue>BNE</stringValue>
Ganzzahl: <intValue>532</intValue> oder <longValue>253456345</longValue>
Zahl: <doubleValue>34.34</doubleValue>
Zahl mit hoher Genauerigkeit: <bigDecimalValue>1234567890.0987654321</bigDecimalValue>
Wahrheitswert: <booleanValue>true</booleanValue>
Funktion | Einsetzbar für Datentyp |
|---|---|
IS_EMPTY | Text, Zahl, Große Textfelder, Datum |
IS_NOT_EMPTY | Text, Zahl, Große Textfelder, Datum |
IS_EQUAL | Text, Nachschlagefeld, Zahl, Wahrheitswert, Datum |
IS_NOT_EQUAL | Text, Nachschlagefeld, Zahl, Datum |
STARTS_WITH | Text, Nachschlagefeld, Große Textfelder |
STARTS_NOT_WITH | Text, Nachschlagefeld, Große Textfelder |
ENDS_WITH | Text, Nachschlagefeld, Große Textfelder |
ENDS_NOT_WITH | Text, Nachschlagefeld, Große Textfelder |
CONTAINS | Text, Nachschlagefeld, Datum |
CONTAINS_NOT | Text, Nachschlagefeld, Datum |
IS_SMALLER_THEN | Text, Nachschlagefeld, Zahl, Datum |
IS_GREATER_THEN | Text, Nachschlagefeld, Zahl, Datum |
IS_EQUAL_OR_SMALLER_THEN | Text, Nachschlagefeld, Zahl, Datum |
IS_EQUAL_OR_GREATER_THEN | Text, Nachschlagefeld, Zahl, Datum |
EntityLookupField
Um Lookup-Felder zu füllen, bei denen der Wert nicht bekannt ist, sollte das EntityLookupField-Tag verwendet werden. In name wird der Attributename des zu füllenden Feldes angegeben. Dann können beliebig viele Field-Tags angegeben werden um den Wert eindeutig zu identifizieren. Diese sollten jeweils das identifyingField Attribut auf true gesetzt haben.
<EntityLookupField name="DefaultContactPerson.Activity">
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Cornelia</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Altenhain</stringValue>
</FieldValue>
</Field>
<Field name="CustomerKey.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>CURSOR GIESSEN</stringValue>
</FieldValue>
</Field>
</EntityLookupField>
Ab Version 11.2 kann identifyingField analog zu dem Attribut auf dem Field-Tag genutzt werden. Dies legt fest ob bei der Suche nach bestehenden Daten dieses Feld mit einbezogen wird.
<EntityLookupField name="DefaultContactPerson.Activity" identifyingField="true">
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Cornelia</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Altenhain</stringValue>
</FieldValue>
</Field>
<Field name="CustomerKey.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>CURSOR GIESSEN</stringValue>
</FieldValue>
</Field>
</EntityLookupField>
Link
Alternativ zur Schachtelung von Datensätzen kann das Link-Tag verwendet werden um Verknüpfungen zu erstellen.
pk muss den Primärschlüssel des zu verknüpfenden Datensatzes enthalten.
entity muss die Entität des zu verknüpfenden Datensatzes enthalten.
relation muss die Relation zwischen dem aktuellen und dem zu verknüpfenden Datensatzes enthalten.
<Link pk="ged-activitypkToepper4" entity="Activity" relation="rCoPeAc"/>
Ausgabe
Zurückgegeben werden alle Field-Tags, die als identifizierend markiert sind, alle Link-Tags, sowie alle EntityLookupFields. Hinzu kommen eine Reihe weiterer informativer Tags. Ein Beispiel für eine Rückgabestruktur:
<Entries success="true">
<Config testRun="false" version="9.2" transactionTime="300"/>
<Entry found="ZERO" action="CREATE" entity="Activity">
<CompletionType>SUCCESS</CompletionType>
<ModificationType>CREATE</ModificationType>
<PrimaryKeys>
<Pk value="3fnvmsi143btagn0Ac"/>
</PrimaryKeys>
<Field identifyingField="true" name="Subject.Activity">
<FieldValue>
<stringValue>Umstieg Lohn: Zentralverband Elektrotechnik</stringValue>
</FieldValue>
</Field>
<Field identifyingField="true" name="FreeText2.Activity">
<FieldValue>
<stringValue>Umstieg kann erfolgen.</stringValue>
</FieldValue>
</Field>
</Entry>
</Entries>
Tags und deren Attribute der Rückgabe
Tags | Attribute | Defaultwert | Mögliche Werte |
|---|---|---|---|
Entries | success | Wert wird in Antwort gesetzt | Status des Imports: Erfolg/Misserfolg |
ErrorMessage | - | - | - |
CompletionType | type | Wird vom System passend gesetzt | SUCCESS, ERROR |
ModificationType | type | Wird vom System passend gesetzt | CREATE, UPDATE, DELETE, LINK, UNLINK, NO_MODIFICATION |
Pk | value | Wird vom System passend gesetzt | Der Pk des bearbeiteten Datensatzes |
Entries
In der Rückgabestruktur hat das Entries-Tag das Attribut success. Anhand dieses Attributs kann auf den ersten Blick erkannt werden ob der Import funktioniert hat, oder ob irgendwo ein Fehler aufgetreten ist.
<Entries success="true">
ErrorMessage
Im ErrorMessage-Tag werden jegliche Fehlermeldungen angezeigt. Es kann unterhalb von Entry, Field und EntityLookupField auftauchen.
<ErrorMessage>Das Feld existiert nicht in dieser Entität!</ErrorMessage>
CompletionType
Das CompletionType-Tag zeigt an ob ein Entry erfolgreich bearbeitet wurde, oder nicht.
<CompletionType>SUCCESS</CompletionType>
ModificationType
Der ModificationType gibt an was an dem Entry geändert wurde. Wurde der Datensatz beispielsweise aktualisiert wurde hier UPDATE stehen. Wenn nichts passiert ist wäre der Wert NO_MODIFICATION. Dabei kann auch im Erfolgsfall NO_MODIFICATION angegeben sein, beispielsweise wenn nur gelöscht werden soll, wenn exakt ein Datensatz gefunden wurde (found="ONE").
<ModificationType>CREATE</ModificationType>
PrimaryKeys
Das 'PrimaryKeys'-Tag dient nur dem sammeln der Pk-Tags und hat keine weiteren Attribute.
Pk
In Pk-Tags werden (im value-Attribute) die Pks aller Datensätze zurückgegeben, die Einfluss auf die abgearbeiteten Aktionen hatten. Beispielsweise werden die Pks von angelegten, aktualisierten, gelöschten oder verlinkten Datensätzen zurück gegeben. Aber auch die Pks aller anhand der identifizierenden Felder gefundener Datensätze, wenn nichts getan wurde weil so keine Eindeutigkeit bestand.
<Pk value="3fnvmsi143btagn0Ac"/>
Tag Reihenfolge
Folgende Reihenfolge der Tags ist einzuhalten:
Config
Entry
Field
EntityLookupField
Link
Entry
Field
...
Entry
...
<Entries>
<Config transactionTime="" version="" testRun=""/>
<Entry entity="" action="" found="" rightTemplate="">
<Field name="" identifyingField="">
<FieldValue>
<stringValue></stringValue>
</FieldValue>
</Fields>
<Field name="" identifyingField="">
<FieldValue>
<stringValue></stringValue>
</FieldValue>
</Fields>
<EntityLookupField name="">
<Field name="" value="" identifyingField=""/>
</EntityLookupField>
<EntityLookupField name="">
<Field name="" value="" identifyingField=""/>
</EntityLookupField>
<Link pk="" entity="" relation=""/>
<Link pk="" entity="" relation=""/>
<Link pk="" entity="" relation=""/>
<Entry entity="" action="" found="" relation="">
...
</Entry>
</Entry>
<Entry entity="" action="" found="" rightTemplate="">
...
</Entry>
</Entries>
Aktionen
Datensatz anlegen
Das folgende Beispiel importiert eine Aktivität, wenn keine andere Aktivität mit dem selben Betreff gefunden wird.
<Entry entity="Activity" action="CREATE" found="ZERO">
<Field name="Subject.Activity" identifyingField="true">
<FieldValue>
<stringValue>Bestätigung</stringValue>
</FieldValue>
</Field>
<Field name="Text.Activity" identifyingField="false">
<FieldValue>
<stringValue>Der Eingang der Angebotsdokumente wurde bestätigt.</stringValue>
</FieldValue>
</Field>
<Field name="DelegatedBy.Activity" identifyingField="false">
<FieldValue>
<stringValue>BNE</stringValue>
</FieldValue>
</Field>
<Field name="DelegatedTo.Activity">
<FieldValue>
<stringValue>BNE</stringValue>
</FieldValue>
</Field>
<Field name="ActStatusKey.Activity">
<FieldValue>
<stringValue>O</stringValue>
</FieldValue>
</Field>
<Field name="ActTypeKey.Activity">
<FieldValue>
<stringValue>TELEIN</stringValue>
</FieldValue>
</Field>
<Field name="StartDate.Activity">
<FieldValue>
<dateTimeValue>2008-04-20T17:00:00</dateTimeValue>
</FieldValue>
</Field>
<Field name="EndDate.Activity">
<FieldValue>
<dateTimeValue>2008-04-27T17:00:00</dateTimeValue>
</FieldValue>
</Field>
<Field name="FreeNumber1.Activity" identifyingField="false">
<FieldValue>
<doubleValue>42.0</doubleValue>
</FieldValue>
</Field>
<Field name="DefaultOpportunity.Activity" identifyingField="false" fieldType="PK">
<FieldValue>
<stringValue>ged-opportunitypk3</stringValue>
</FieldValue>
</Field>
<EntityLookupField name="DefaultContactPerson.Activity">
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Cornelia</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Altenhain</stringValue>
</FieldValue>
</Field>
<Field name="CustomerKey.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>CURSOR GIESSEN</stringValue>
</FieldValue>
</Field>
</EntityLookupField>
</Entry>
Datensatz löschen
Ein Datensatz kann nur durch den Modus DELETE_DATA entfernt werden und nicht durch setzen des Active-Feldes. Das folgende Beispiel löscht alle Anfragen mit einem Anfragewert von 42,42 und der Beschreibung "Meine Anfrage".
<Entry entity="Opportunity" action="DELETE_DATA" found="N">
<Field name="OpName.Opportunity" identifyingField="true">
<FieldValue>
<stringValue>Meine Anfrage</stringValue>
</FieldValue>
</Field>
<Field name="Projectvalue.Opportunity" identifyingField="true">
<FieldValue>
<doubleValue>42.42</doubleValue>
</FieldValue>
</Field>
</Entry>
Hier hingegen wird nur ein Datensatz gezielt gelöscht, erfüllen mehrere Datesätze die Suchkriterien passiert nichts.
<Entry entity="Opportunity" action="DELETE_DATA" found="ONE">
<Field name="OpName.Opportunity" identifyingField="true">
<FieldValue>
<stringValue>Meine Anfrage</stringValue>
</FieldValue>
</Field>
<Field name="Projectvalue.Opportunity" identifyingField="true">
<FieldValue>
<doubleValue>42.42</doubleValue>
</FieldValue>
</Field>
</Entry>
Datensatz reaktivieren
Soll ein gelöschter Datensatz reaktivert werden, muss das Active-Feld auf true gesetzt werden. Im selben Durchlauf können auch weitere Aktualisierungen erfolgen. Dieses Beispiel reaktiviert den Ansprechpartner Carl Meyer, sofern dieser gelöscht ist, und setzt seinen Typ auf H. Existiert noch kein Carl Meyer, wird er angelegt.
<Entry entity="ContactPerson" action="UPDATE_OR_CREATE" found="ONE">
<Field name="MatchCode.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>CARL MEYER</stringValue>
</FieldValue>
</Field>
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Carl</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Meyer</stringValue>
</FieldValue>
</Field>
<Field name="Sex.ContactPerson">
<FieldValue>
<stringValue>H</stringValue>
</FieldValue>
</Field>
<Field name="Active.ContactPerson">
<FieldValue>
<booleanValue>true</booleanValue>
</FieldValue>
</Field>
</Entry>
Datensätze verknüpfen
Um Datensätze zu verknüpfen, müssen sie geschachtelt werden. Dabei ist es egal ob sie erstellt, aktualisiert oder nur verknüpft werden. Dieses Beispiel verknüpft den Vertrag mit der Bezeichnung "Vertrag mit Kleingedrucktem" und der Nummer "4815162342" mit dem gerade erstellten Projekt. Da alle Felder als identifizierend markiert sind, wird dabei nichts aktualisiert. Existiert kein solcher Vertrag wird einer erstellt und dann verknüpft.
<Entry entity="Project" action="CREATE" found="NO_SEARCH">
<Field name="Matchcode.Project">
<FieldValue>
<stringValue>GROSSPROJEKT</stringValue>
</FieldValue>
</Field>
<Field name="CoordinatorKey.Project">
<FieldValue>
<stringValue>BNE</stringValue>
</FieldValue>
</Field>
<Field name="DefaultCustomer.Project">
<FieldValue>
<stringValue>DEUTSCHE BANK</stringValue>
</FieldValue>
</Field>
<Entry entity="Contract" action="LINK_AND_UPDATE_OR_CREATE" found="ONE" relation="rCnPj">
<Field name="ContTitle.Contract" identifyingField="true">
<FieldValue>
<stringValue>Vertrag mit Kleingedrucktem</stringValue>
</FieldValue>
</Field>
<Field name="ContNo.Contract" identifyingField="true">
<FieldValue>
<stringValue>4815162342</stringValue>
</FieldValue>
</Field>
</Entry>
</Entry>
Alternativ kann das Link-Tag verwendet werden.
Datensatzverknüpfung löschen
Um die Verknüpfung zwischen 2 Datensätzen zu entfernen, nicht aber die Datensätze selbst, ist die Aktion DELETE_LINK vorgesehen.
<Entry entity="Customer" action="UPDATE" found="ONE">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue>
<stringValue>ADAC MÜNCHEN ZENTRALE - INTERESSEN</stringValue>
</FieldValue>
</Field>
<Field name="Name1.Customer" identifyingField="true">
<FieldValue>
<stringValue>ADAC e.V.</stringValue>
</FieldValue>
</Field>
<Entry entity="Customer" action="DELETE_LINK" found="ONE" relation="rCuCu">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue>
<stringValue>CURSOR ENTWICKLUNG</stringValue>
</FieldValue>
</Field>
<Field name="Name1.Customer" identifyingField="true">
<FieldValue>
<stringValue>CURSOR Software AG</stringValue>
</FieldValue>
</Field>
<Field name="Name2.Customer" identifyingField="true">
<FieldValue>
<stringValue>Entwicklung</stringValue>
</FieldValue>
</Field>
</Entry>
</Entry>
Datensatz aktualisieren
Ein oder mehrere Datensätze können folgendermaßen aktualisiert werden.
<Entry entity="ContactPerson" action="UPDATE" found="ONE">
<Field name="MatchCode.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>BEN LINUS</stringValue>
</FieldValue>
</Field>
<Field name="FirstName.ContactPerson">
<FieldValue>
<stringValue>Benjamin</stringValue>
</FieldValue>
</Field>
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue>
<stringValue>Linus</stringValue>
</FieldValue>
</Field>
<Field name="Sex.ContactPerson">
<FieldValue>
<stringValue>H</stringValue>
</FieldValue>
</Field>
<Link pk="ged-activitypkToepper4" entity="Activity" relation="rCoPeAc"/>
</Entry>
Behandlung von Rollen, Adressen und Telekommunikation
Das Anlegen von Rollen Geschäftspartner, Ansprechpartner bzw. Mitarbeiter ist besonderen Einschränkungen aufgrund der speziellen Datenstruktur unterworfen.
Legt der Benutzer eine Rolle an, so werden automatisch eine Person, eine Adresse sowie mehrere Telekommunikations-Datensätze angelegt. Im Geschäftspartner sind Felder der Adresse delegiert, welche bei der Neuanlage oder beim Update direkt gesetzt werden können. Gleiches gilt für die Telekommunikation. Eine Adresse und eine Telekommunikation kann immer nur abhängig von einer Rolle bearbeitet werden, d.h. der Entry-Eintrag muss verschachtelt angegeben sein.
Das erste Beispiel legt einen neuen Geschäftspartner an, bei dem die Adresse und Telefonnummern direkt gespeichert werden. Die Telekommunikation wird als Standard Telekommunikation gespeichert. Die Adresse wird als Anzeige-, Post- und Standard-Adresse gespeichert.
<Entries>
<Config transactionTime="2000" version="9.2.0" testRun="false"/>
<Entry entity="Customer" action="CREATE" found="ZERO">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue><stringValue>MUSTERMANN AG</stringValue></FieldValue>
</Field>
<Field name="Name1.Customer" identifyingField="false" >
<FieldValue><stringValue>Mustermann</stringValue></FieldValue>
</Field>
<Field name="Name2.Customer" identifyingField="false" >
<FieldValue><stringValue>AG</stringValue></FieldValue>
</Field>
<Field name="PeAddressType.Customer" identifyingField="false" >
<FieldValue><stringValue>STRASSE</stringValue></FieldValue>
</Field>
<Field name="PeStreet.Customer" identifyingField="false" >
<FieldValue><stringValue>Hauptstraße</stringValue></FieldValue>
</Field>
<Field name="PeStreetNumber.Customer" identifyingField="false" >
<FieldValue><stringValue>1</stringValue></FieldValue>
</Field>
<Field name="PeCity.Customer" identifyingField="false" >
<FieldValue><stringValue>Hauptstadt</stringValue></FieldValue>
</Field>
<Field name="PeZIP.Customer" identifyingField="false" >
<FieldValue><stringValue>10000</stringValue></FieldValue>
</Field>
<Field name="PhoneNoCountry.Customer" identifyingField="false" >
<FieldValue><stringValue>+49</stringValue></FieldValue>
</Field>
<Field name="PhoneNoCity.Customer" identifyingField="false" >
<FieldValue><stringValue>01234</stringValue></FieldValue>
</Field>
<Field name="PhoneNoBase.Customer" identifyingField="false" >
<FieldValue><stringValue>56789</stringValue></FieldValue>
</Field>
<Field name="PhoneNoExtension.Customer" identifyingField="false" >
<FieldValue><stringValue>0</stringValue></FieldValue>
</Field>
</Entry>
</Entries>
Sollen weitere Felder der Adresse eingetragen werden (z.B. Freifelder), so muss dies per Update auf der Adresse passieren, da die Adresse bei der Neuanlage des Geschäftspartner automatisch angelegt wird. Mit einem Geschäftspartner können mehrere Adressen verknüpft sein, so dass identifizierende Felder aufgenommen werden müssen. Bei Adressen zu Geschäftspartner sind das die Felder Anzeige- (DefaultCuAd.Address) bzw. Postadresse (LetterCuAd.Address).
Bei der Telekommunikation ist das Feld Standard Telekommunikation (IsDefault) das identifizierende Feld.
<Entries>
<Config transactionTime="2000" version="9.2.0" testRun="false"/>
<Entry entity="Customer" action="CREATE" found="ZERO">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue><stringValue>MUSTERMANN2 AG</stringValue></FieldValue>
</Field>
<Field name="Name1.Customer" identifyingField="false" >
<FieldValue><stringValue>Mustermann2</stringValue></FieldValue>
</Field>
<Field name="Name2.Customer" identifyingField="false" >
<FieldValue><stringValue>AG</stringValue></FieldValue>
</Field>
<Entry entity="Address" action="UPDATE" found="ONE" relation="rCuAd">
<Field name="DefaultCuAd.Address" identifyingField="true">
<FieldValue><booleanValue>true</booleanValue></FieldValue>
</Field>
<Field name="LetterCuAd.Address" identifyingField="true">
<FieldValue><booleanValue>true</booleanValue></FieldValue>
</Field>
<Field name="City.Address" identifyingField="false">
<FieldValue><stringValue>Hauptstadt</stringValue></FieldValue>
</Field>
<Field name="CountryKey.Address" identifyingField="false">
<FieldValue><stringValue>D</stringValue></FieldValue>
</Field>
<Field name="AddressType.Address" identifyingField="false">
<FieldValue><stringValue>STRASSE</stringValue></FieldValue>
</Field>
<Field name="NameKey.Address" identifyingField="false">
<FieldValue><stringValue>BÜRO</stringValue></FieldValue>
</Field>
<Field name="Street.Address" identifyingField="false">
<FieldValue><stringValue>Hauptstraße</stringValue></FieldValue>
</Field>
<Field name="StreetNumber.Address" identifyingField="false">
<FieldValue><stringValue>1</stringValue></FieldValue>
</Field>
<Field name="StreetNumberAddition.Address" identifyingField="false">
<FieldValue><stringValue>a</stringValue></FieldValue>
</Field>
<Field name="ZIPKey.Address" identifyingField="false">
<FieldValue><stringValue>10000</stringValue></FieldValue>
</Field>
<Field name="State.Address" identifyingField="false">
<FieldValue><stringValue>Berlin</stringValue></FieldValue>
</Field>
</Entry>
<Entry entity="Telecom" action="UPDATE" found="ONE" relation="CuTe">
<Field name="IsDefault.Telecom" identifyingField="true">
<FieldValue><booleanValue>true</booleanValue></FieldValue>
</Field>
<Field name="PhoneNoCountry.Telecom" identifyingField="false">
<FieldValue><stringValue>+49</stringValue></FieldValue>
</Field>
<Field name="PhoneNoCity.Telecom" identifyingField="false">
<FieldValue><stringValue>01234</stringValue></FieldValue>
</Field>
<Field name="PhoneNoBase.Telecom" identifyingField="false">
<FieldValue><stringValue>56789</stringValue></FieldValue>
</Field>
<Field name="PhoneNoExtension.Telecom" identifyingField="false">
<FieldValue><stringValue>0</stringValue></FieldValue>
</Field>
<Field name="NameKey.Telecom" identifyingField="false">
<FieldValue><stringValue>BÜRO</stringValue></FieldValue>
</Field>
<Field name="Email.Telecom" identifyingField="false">
<FieldValue><stringValue>info@mustermannag.de</stringValue></FieldValue>
</Field>
</Entry>
</Entry>
</Entries>
Um eine weitere Adresse, z.B. ein Postfach, anzulegen und diese als Postadresse des Geschäftspartner zu markieren, müssen die Felder Post- bzw. Anzeigeadresse korrekt gesetzt werden. Im Beispiel wird zu der bereits vorhandenen Adresse eine zweite Adresse angelegt und als Postadresse markiert.
<Entries>
<Config transactionTime="2000" version="9.2.0" testRun="true"/>
<Entry entity="Customer" action="CREATE" found="ZERO">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue><stringValue>MUSTERMANN3 AG</stringValue></FieldValue>
</Field>
<Field name="Name1.Customer" identifyingField="false" >
<FieldValue><stringValue>Mustermann3</stringValue></FieldValue>
</Field>
<Field name="Name2.Customer" identifyingField="false" >
<FieldValue><stringValue>AG</stringValue></FieldValue>
</Field>
<Field name="PeAddressType.Customer" identifyingField="false" >
<FieldValue><stringValue>STRASSE</stringValue></FieldValue>
</Field>
<Field name="PeStreet.Customer" identifyingField="false" >
<FieldValue><stringValue>Hauptstraße</stringValue></FieldValue>
</Field>
<Field name="PeStreetNumber.Customer" identifyingField="false" >
<FieldValue><stringValue>1</stringValue></FieldValue>
</Field>
<Field name="PeCity.Customer" identifyingField="false" >
<FieldValue><stringValue>Hauptstadt</stringValue></FieldValue>
</Field>
<Field name="PeZIP.Customer" identifyingField="false" >
<FieldValue><stringValue>10000</stringValue></FieldValue>
</Field>
<Field name="PhoneNoCountry.Customer" identifyingField="false" >
<FieldValue><stringValue>+49</stringValue></FieldValue>
</Field>
<Field name="PhoneNoCity.Customer" identifyingField="false" >
<FieldValue><stringValue>01234</stringValue></FieldValue>
</Field>
<Field name="PhoneNoBase.Customer" identifyingField="false" >
<FieldValue><stringValue>56789</stringValue></FieldValue>
</Field>
<Field name="PhoneNoExtension.Customer" identifyingField="false" >
<FieldValue><stringValue>0</stringValue></FieldValue>
</Field>
<Entry entity="Address" action="CREATE" found="ZERO" relation="rCuAd">
<Field name="AddressType.Address" identifyingField="true">
<FieldValue><stringValue>POSTFACH</stringValue></FieldValue>
</Field>
<Field name="DefaultCuAd.Address" identifyingField="false">
<FieldValue><booleanValue>false</booleanValue></FieldValue>
</Field>
<Field name="LetterCuAd.Address" identifyingField="false">
<FieldValue><booleanValue>true</booleanValue></FieldValue>
</Field>
<Field name="City.Address" identifyingField="false">
<FieldValue><stringValue>Hauptstadt</stringValue></FieldValue>
</Field>
<Field name="CountryKey.Address" identifyingField="false">
<FieldValue><stringValue>D</stringValue></FieldValue>
</Field>
<Field name="NameKey.Address" identifyingField="false">
<FieldValue><stringValue>BÜRO</stringValue></FieldValue>
</Field>
<Field name="ZIPKey.Address" identifyingField="false">
<FieldValue><stringValue>10001</stringValue></FieldValue>
</Field>
<Field name="Street.Address" identifyingField="false">
<FieldValue><stringValue>Postfach</stringValue></FieldValue>
</Field>
<Field name="State.Address" identifyingField="false">
<FieldValue><stringValue>Berlin</stringValue></FieldValue>
</Field>
</Entry>
</Entry>
</Entries>
Beim Update oder Neuanlage von Adressen und Telekommunikation werden die Daten in den abhängigen Rollen aktualisiert.
Übernahme von Adressen
Ein weitere Sonderbehandlung gibt es zwischen Ansprechpartner und Geschäftspartner:
Bei dieser XML Struktur erhält der Ansprechpartner Verknüpfungen zu allen Geschäftspartneradressen:
<Entries>
<Config transactionTime="350" version="13.1" testRun="false" />
<Entry entity="Customer" action="UPDATE" found="ONE">
<Field name="MatchCode.Customer" identifyingField="true">
<FieldValue><stringValue>BEISPIEL GMBH</stringValue></FieldValue>
</Field>
<Entry entity="ContactPerson" action="CREATE" relation="rCustomerKey_ContactPerson" found="ZERO">
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue><stringValue>Müller</stringValue></FieldValue>
</Field>
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue><stringValue>Hans</stringValue></FieldValue>
</Field>
</Entry>
</Entry>
</Entries>
Bei dieser nicht:
<Entries>
<Config transactionTime="350" version="13.1" testRun="false" />
<Entry entity="ContactPerson" action="CREATE" found="ZERO">
<Field name="LastName.ContactPerson" identifyingField="true">
<FieldValue><stringValue>Müller</stringValue></FieldValue>
</Field>
<Field name="FirstName.ContactPerson" identifyingField="true">
<FieldValue><stringValue>Hans</stringValue></FieldValue>
</Field>
<Entry entity="Customer" action="LINK_AND_UPDATE" found="ONE">
<Field name="MatchCode.Customer" identifyingField="true" relation="rCustomerKey_ContactPerson">
<FieldValue><stringValue>BEISPIEL GMBH</stringValue></FieldValue>
</Field>
</Entry>
</Entry>
</Entries>
Besonderheit: Aktionen auf Schlüsseltabellen (S_Keytab/KeyTabNum oder KeyRange)
Grundsätzlich werden die Aktionen in der XML-Datei auf die gleiche Weise wie beschrieben definiert. Allerdings gibt es bei Aktionen auf Schlüsseltabellen einige Einschränkungen, auf die bei der Verwendung des XML-Imports geachtet werden muss.
Die Aktionen werden immer auf höchster Ebene (TopLevel) ausgeführt. Es ist nicht möglich, mehrere <Entry>-Einträge zu schachteln, weil keine Relationen unter Schlüsseln existieren.
Folgende Aktionen sind bei Schlüsseltabellen nicht anwendbar:
LINK_AND_UPDATE, LINK_AND_UPDATE_OR_CREATE, DELETE_LINK:
Da keine Relationen existieren, können auch keine LINK-Operationen durchgeführt werden.
UPDATE_OR_CREATE (ONE / N)
Da für eine UPDATE oder CREATE Aktion verschiedene Vorbedingungen geprüft werden müssen (siehe unten) und dazu bereits im Parser Suchen ausgeführt werden müssten, um die korrekte Syntax zu prüfen, wurden diese Aktionen verboten.
Es ist aktuell nicht möglich, in einer einzigen XML-Datei zuerst eine KeyRange anzulegen und zu dieser Range direkt im Anschluss neue Schlüssel anzulegen. Die neu angelegte Range kann in der gleichen Transaktion noch nicht verwendet werden (wird in 9.2.50 bearbeitet).
Neben diesen grundsätzlichen Einschränkungen, müssen für die verbleibenden Aktionen bestimmte Vorbedingungen eingehalten werden.
CREATE
S_Keytab/KeyTabNum --- Bei der Neuanlage von Schlüsseln müssen zwingend die Felder KeyName + KeyRange angegeben werden.
Beispiel:
<Entry entity="KeytabNum" action="CREATE" found="ZERO">
<Field name="Pk.KeytabNum" identifyingField="true">
<FieldValue>
<stringValue>TESTKEY1</stringValue>
</FieldValue>
</Field>
<!-- Error: KeyName.KeytabNum muss bei dieser Aktion zwingend angegeben werden.-->
<Field name="DisplayName.KeytabNum" identifyingField="false">
<FieldValue>
<stringValue>Testschlüssel</stringValue>
</FieldValue>
</Field>
<!-- Error: KeyRange.KeytabNum muss bei dieser Aktion zwingend angegeben werden. -->
</Entry>
KeyRange --- Bei der Neuanlage von Schlüsselbereichen müssen zwingend die Felder Pk + DataType angegeben werden.
Beispiel:
<Entry entity="KeyRange" action="CREATE" found="ZERO">
<!-- Error: Pk.KeyRange muss bei dieser Aktion zwingend angegeben werden. -->
<Field name="Description.KeyRange" identifyingField="true">
<FieldValue>
<stringValue>Testrange String 1</stringValue>
</FieldValue>
</Field>
<Field name="DataType.KeyRange" identifyingField="false">
<FieldValue>
<stringValue>java.lang.String</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry entity="KeyRange" action="CREATE" found="ZERO">
<Field name="Pk.KeyRange" identifyingField="true">
<FieldValue>
<stringValue>TEST_RANGE_STRING2</stringValue>
</FieldValue>
</Field>
<Field name="Description.KeyRange" identifyingField="false">
<FieldValue>
<stringValue>Testrange String 1</stringValue>
</FieldValue>
</Field>
<!-- Error: DataType.KeyRange muss bei dieser Aktion zwingend angegeben werden. -->
</Entry>
UPDATE + N
S_Keytab/KeyTabNum --- Diese Aktion liefert im Normalfall mehrere Datensätze als Suchergebnis. In allen Datensätzen werden dann die angegebenen Felder auf die gleichen Werte gesetzt. Daher müssen bei dieser Aktion die Felder Pk + KeyName als IdentifyingFields definiert werden oder weggelassen werden. Werden sie als Id-Fields definiert, liefert die Suche nur noch ein einziges Ergebnis und die Aktion ist äquivalent zu UPDATE + ONE. Es ist nicht möglich, bei mehreren Datensätzen diese Felder auf den gleichen Wert zu setzten. Dadurch ginge die Eindeutigkeit der Schlüssel verloren.
Beispiel:
<Entry entity="KeytabNum" action="UPDATE" found="N">
<!-- Error: Pk kann nicht mit UPDATE + N verändert werden. Entweder identifyingField = true oder Feld entfernen. -->
<Field name="Pk.KeytabNum" identifyingField="false">
<FieldValue>
<stringValue>TESTKEY1</stringValue>
</FieldValue>
</Field>
<Field name="DisplayName.KeytabNum" identifyingField="true">
<FieldValue>
<stringValue>Testschlüssel</stringValue>
</FieldValue>
</Field>
<!-- Error: KeyName kann nicht mit UPDATE + N verändert werden. Entweder identifyingField = true oder Feld entfernen. -->
<Field name="KeyName.KeytabNum" identifyingField="false">
<FieldValue>
<intValue>212345</intValue>
</FieldValue>
</Field>
<Field name="KeyRange.KeytabNum" identifyingField="false">
<FieldValue>
<stringValue>S_PRJSTA</stringValue>
</FieldValue>
</Field>
<Field name="ParentPk.KeytabNum" identifyingField="false">
<FieldValue>
<stringValue>S_PRJSTA-100</stringValue>
</FieldValue>
</Field>
</Entry>
Besonderheit: Aktionen auf Angebotspositionen (QuoteItem)
Angebotspoisitonen müssen immer unterhalb eines ANgebots angelegt werden und zusätzlich muss der Positions-Satz den QuotePK enthalten.
<Entry entity="Quote" action="UPDATE" found="ONE">
<Field name="Quoteno.Quote" identifyingField="true">
<FieldValue>
<stringValue>ANG 0000002</stringValue>
</FieldValue>
</Field>
<Entry entity="QuoteItem" action="CREATE" found="NO_SEARCH" relation="rQuotePK_QuoteItem">
<Field name="QuotePK.QuoteItem" fieldType="PK">
<FieldValue>
<stringValue>fvvvvvv7hk88i1am8op7sgQu</stringValue>
</FieldValue>
</Field>
...
</Entry>
</Entry>
Probleme/Lösungen
Folgende Probleme bei der Benutzung der Schnittstelle sind bekannt:
Composed-Felder
Die Felder ComposedAddress, ComposedFax, ComposedMobilePhone und ComposedPhone auf den verschiedenen Rollen können nicht gesetzt werden. Die XML-Import-Schnittstelle ignoriert entsprechende Eingaben, da diese Felder aus mehreren anderen Feldern zusammengesetzt werden und in der Anwendung nur zum Lesen sind. Hier bitte die einzelnen Felder füllen (Beispiel ComposedPhone: PhoneNoCountry, PhoneNoCity, PhoneNoBase und PhoneNoExtension) .
Gelöschte Daten
Die Rückgabestruktur zeigt an, dass ein entsprechender Datensatz bereits existiert, in der Anwendung kann aber keiner gefunden werden? Die XML-Import Schnittstelle findet auch gelöscht Datensätze um diese auf Wunsch reaktivieren zu können. Mit hoher Wahrscheinlichkeit existiert ein entsprechender Eintrag bereits und ist lediglich deaktiviert.
Sonderzeichen
Sollen die Zeichen &, < oder > genutzt werden, muss um das entsprechende Feld ein CDATA-Block gesetzt werden, da sonst kein valides XML mehr gegeben wäre. Beispiel:
<Entries>
<Config transactionTime="36000" version="9.2" testRun="false"/>
<Entry entity="Activity" action="CREATE" found="ZERO">
<Field name="Subject.Activity" identifyingField="true">
<FieldValue>
<stringValue><![CDATA[Anruf Müller & Söhne]]></stringValue>
</FieldValue>
</Field>
</Entry>
</Entries>
Nachschlagefelder mit Validierungsfeldern
Nachschlagefelder mit eingetragenen Validierungsfeldern können nicht korrekt behandelt werden und erzeugen die Nachricht "Die Validierung des Nachschlagefeldes ist fehlgeschlagen.". In der Auslieferungsversion trifft dies nur auf das Feld 'DefaultContactPerson.Activity' zu. Um das Problem zu umgehen sollte hier das 'EntityLookupField'-Tag eingesetzt oder statt dem Wert der Pk genutzt werden (fieldType="PK").
Zu viele Datensätze gefunden
Die XML-Import Schnittstelle findet auch inaktive Datensätze.
Wenn für die eingegebenen Kriterien mehr Datensätze gefunden werden als erwartet, handelt es sich dabei eventuell um inaktive Datensätze. Um diese auszuschließen muss das 'Active' Feld als identifizierend makriert werden. Beispiel auf der Aktivität:
<Field name="Active.Activity" identifyingField="true">
<FieldValue>
<stringValue>true</stringValue>
</FieldValue>
</Field>
Falsche Codierung der Templatedatei
Tritt eine Fehlermeldung folgender Art auf, ist sehr wahrscheinlich der CURSOR-Importer genutzt worden und dessen Templatedatei wurde falsch codiert. Zur Erinnerung: Sie muss "UTF-8 ohne BOM" codiert sein.
org.apache.axis2.AxisFault: de.cursor.util.xml.binding.XMLBindingException: javax.xml.bind.UnmarshalException
- with linked exception:
[org.xml.sax.SAXParseException: cvc-complex-type.2.3: Element 'Entries' cannot have character [children],
because the type's content type is element-only.]
Felder leeren
Versucht man ein Feld zu "leeren", kommt es bei Zahl-, Boolean- oder Datumsfeldern zu einer Fehlermeldung dieser Art:
[org.xml.sax.SAXParseException: cvc-datatype-valid.1.2.1: '' is not a valid value for 'double'.]
In Diesem Fall sind zwei Änderungen an der XML-Struktur nötig:
<Entries xmlns:xs="http://www.w3.org/2001/XMLSchema-instance">
Das Entries-Tag benötigt ein neues Attribut.
<FieldValue>
<dateTimeValue xs:nil="true"/>
</FieldValue>
Das entsprechende Feld muss als leer deklariert werden.
Leerzeichen am Textende
MSSQL, Informix und Oracle verhalten sich bei Leerzeichen am Textende unterschiedlich. Im folgenden XML-Code zum Anlegen von Aktivitäten:
<Entries>
<Config transactionTime="300" version="9.2" testRun="false"/>
<Entry entity="Activity" action="CREATE" found="ZERO">
<Field name="Subject.Activity" identifyingField="true">
<FieldValue>
<stringValue>Mein Betreff</stringValue>
</FieldValue>
</Field>
</Entry>
<Entry entity="Activity" action="CREATE" found="ZERO">
<Field name="Subject.Activity" identifyingField="true">
<FieldValue>
<stringValue>Mein Betreff </stringValue>
</FieldValue>
</Field>
</Entry>
</Entries>
Dieser Code würde unter Oracle dazu führen, dass zwei Aktivitäten angelegt werden. Die erste würde mit dem Betreff "Mein Betreff" angelegt, der zweite Eintrag würde keine Aktivität mit dem Betreff "Mein Betreff " finden und noch eine Aktivität anlegen.
Unter MSSQL, Informix und DB2(unter Windows) würde ebenfalls zunächst eine Aktivität mit dem Betreff "Mein Betreff" angelegt. Der zweite Eintrag würde allerdings bei der Suche nach "Mein Betreff " auch Aktivitäten mit dem Betreff "Mein Betreff" finden, da MSSQL, Informix und DB2(unter Windows) hier ein automatisches Trimmen vornehmen. Das Ergebnis ist, dass hier nur eine Aktivität angelegt wird.
Um diese Probleme zu umgehen, sollten nur Daten ohne Leerzeichen am Textbeginn und Ende angelegt, beziehungsweise die bestehenden Daten bereinigt werden.