Wenn verschiedene Branchen-Software-Lösungen zum Einsatz kommen, ist es eigentlich nur eine Frage der Zeit, bis für dieses und jenes eine Schnittstelle benötigt wird. Meist ist dies eine recht kostspielige Angelegenheit für eine vermeintlich einfache Sache, denn meist werden eigentlich nur Daten aus einer Datenbank über Umwege in eine andere geschrieben. Deshalb kann es nicht schaden, wenn man sich für Kleinigkeiten selbst zu helfen weiß. So lassen sich mit ein paar Minuten Arbeit unter Umständen 20.000€ oder mehr sparen 😉
Hier ist eine Beispiel-XML-Datei mit Lieferdaten. Die XML-Datei hat als Dateiname immer eine Liefernummer und beinhaltet die Produktnummer und Liefermenge von ausgelieferten Produkten:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
<?xml version="1.0"?> <ElDelivery xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"> <xsd:schema xmlns:xsd="https://www.w3.org/2001/XMLSchema" xmlns="" xmlns:prodata="urn:schemas-progress-com:xml-prodata:0001"> <xsd:element name="ElDelivery" prodata:proTempTable="true" prodata:undo="true"> <xsd:complexType> <xsd:sequence> <xsd:element name="ElDeliveryRow" minOccurs="0" maxOccurs="unbounded"> <xsd:complexType> <xsd:sequence> <xsd:element name="PrdNo" type="xsd:int" nillable="true"/> <xsd:element name="DelQty" type="xsd:decimal" nillable="true" prodata:decimals="3"/> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:sequence> </xsd:complexType> </xsd:element> </xsd:schema> <ElDeliveryRow> <PrdNo>10</PrdNo> <DelQty>0.000</DelQtyAsIs> </ElDeliveryRow> |
Die Test-Tabelle in der Datenbank verfügt über die 3 Spalten „Liefernummer“, „Produktnummer“ und „Liefermenge“. Mit folgender SQL-Abfrage kann man nun Daten in eine MSSQL-Datenbank importieren, die man zuvor mittels SELECT-Abfrage aus einer XML-Datei abfragt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
DECLARE @xmlData XML SET @xmlData = ( SELECT * FROM OPENROWSET ( BULK 'C:\Pfad-zu-den-XMLs\001.xml', SINGLE_CLOB ) AS xmlData ); INSERT INTO database.dbo.test SELECT 001, ref.value('PrdNo[1]', 'int'), ref.value('DelQty[1]', 'decimal(10,2)') FROM @xmlData.nodes('/ElDelivery/ElDeliveryRow') xmlData (ref) WHERE ref.value('DelQty[1]', 'decimal(10,2)') != 0; |
Da bei dieser manuellen Abfrage die Liefernummer nicht verfügbar ist, wurde diese zum Test in der SELECT-Abfrage auf ‚001‘ festgesetzt.
Mit folgendem PowerShell-Code wird für jede XML-Datei im Quellverzeichnis die Verbindung zur vorher festgelegten Datenbank geöffnet und mit Hilfe des Dateinamens und des Datei-Inhalts die Datenbank gefüllt:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 |
$dataSource = “DB-Server” $database = “Datenbank” $user = “Benutzer” $pwd = “Kennwort” $connectionString = “Server=$dataSource;uid=$user; pwd=$pwd;Database=$database;Integrated Security=False;” $connection = New-Object System.Data.SqlClient.SqlConnection $connection.ConnectionString = $connectionString $path = Get-ChildItem -Path "C:\Pfad-zu-den-XMLs\*.xml" foreach ($xml in $path) { $connection.Open() $liefernummer = $xml.name -replace '.xml', ''; $query = " DECLARE @xmlData XML SET @xmlData = ( SELECT * FROM OPENROWSET ( BULK '$xml', SINGLE_CLOB ) AS xmlData ); INSERT INTO database.dbo.test SELECT $liefernummer, ref.value('PrdNo[1]', 'int'), ref.value('DelQty[1]', 'decimal(10,2)') FROM @xmlData.nodes('/ElDelivery/ElDeliveryRow') xmlData (ref) WHERE ref.value('DelQty[1]', 'decimal(10,2)') != 0;" $command = $connection.CreateCommand() $command.CommandText = $query $result = $command.ExecuteReader() $connection.Close() Write-Host $liefernummer $xml + ' wurde eingelesen' } |
Wenn die Datenbank z.B. täglich mit neuen Daten gefüttert werden muss, kann man das PowerShell-Skript einfach als Aufgabe über die Aufgabenplanung automatisch ausführen lassen 🙂