Announcement

Collapse
No announcement yet.

Große Menge XML-Dateien in MSSQL-DB einlesen - Frage zur Schemadatei

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Große Menge XML-Dateien in MSSQL-DB einlesen - Frage zur Schemadatei

    Moin in die Runde,
    ich bin "der Neue hier" und habe Euer Forum bei meinem Versuch gefunden, eine funktionierende Schema-Datei für den Import von ca. 1,5 Mio XML-Dateien in eine SQL-Datenbank zu erzeugen.
    Ich bin, was XML angeht, ein ziemlicher Neuling, speziell mit der Frage zu Schemas habe ich mich bisher nicht auseinandergesetzt, das wird sich nun ändern müssen.
    Zu meiner konkreten Herausforderung:

    Ich habe XML-Dateien, die alle den folgenden Aufbau haben:

    Code:
    <?xml version="1.0" encoding="utf-8"?>
    <Document ID="0000a\00d48436-7edc-45c1-ac56-8fe28bfd1f17">
      <Fields>
        <DocumentId Name="DocumentId" Type="System.String" Mandatory="false"><![CDATA[437445]]></DocumentId>
      </Fields>
      <Files>
        <File ID="0001" Name="IrgendEinDocName.doc" Size="55296" MimeType="application/octet-stream" IsEncrypted="false" />
      </Files>
    </Document>
    Bei meiner Recherche habe ich das Vorgehen gefunden, parallel zu der XML-Datei noch eine Schemadatei zu erzeugen und die dann mittels SQLXMLBULKLOAD aus einem VBScript in die Datenbank zu importieren.
    DAS funktioniert rein technisch und die VB-Routine, aus sämtlichen Unterordnern in meiner Dateistruktur die XML-Dateien auszulesen und abzuarbeiten, das ist auch kein Problem.
    Nur mit der Schemadatei tu ich mich schwer.

    Momentan sieht sie wie folgt aus:

    Code:
    <?xml version="1.0" ?>
    <Schema xmlns="urn:schemas-microsoft-com:xml-data"
            xmlns:dt="urn:schemas-microsoft-com:xml:datatypes"  
            xmlns:sql="urn:schemas-microsoft-com:xml-sql" >
    
       <ElementType name="Document" sql:is-constant="1">
          <element type="Fields" />
          <element type="Files" />
       </ElementType>
    
       <ElementType name="Fields"  sql:relation="DocMeta">
        <AttributeType name="DocumentID" dt:type="int" />
          <attribute type="DocumentID"  sql:field="DocumentID" />
       </ElementType>
           <ElementType name="Files"  sql:relation="DocMeta">
               <AttributeType name="ID" dt:type="string" />
               <AttributeType name="Name" dt:type="string" />
               <AttributeType name="Size" dt:type="string" />
               <AttributeType name="MimeType" dt:type="string" />
                <attribute type="ID"  sql:field="FileID" />
                <attribute type="Name"  sql:field="DocName" />
                <attribute type="Size"  sql:field="DocSize" />
                <attribute type="MimeType"  sql:field="MimeType" />
    
       </ElementType>

    </Schema>

    Wenn ich das Script nun mit einer Beispieldatei laufen lasse, erzeugt es mir in meiner Datenbank zwei leere Datensätze, die Felder haben jeweils den Wert NULL.
    Meine Tabelle DocMeta hat die fünf Spalten

    DocumentID,
    FileID,
    DocName,
    DocSize,
    MimeType


    Hat von Euch jemand einen Tipp für mich, wie ich die Schemadatei ändern muss, damit die Inhalte aus dem XML in die Datenbank übertragen werden?

    Ich danke Euch schon jetzt ganz herzlich und wünsche ein feines Wochenende!

    Viele Grüße
    Dimo
    Zuletzt editiert von Dimo Tabken; 16.05.2020, 10:23.

  • Dimo Tabken
    replied
    Das mag sein, Christian.
    Es ist aber eine einmalige Aktion, für die ich das Gerümpel brauche, daher werde ich den Import mal so laufen lassen und wenn's die Zeit dann mal hergibt, werde ich mich damit befassen, wie sowas sinnvoller gelöst werden kann.
    Zunächst brauche ich in absehbarer Zeit eine Lösung und der jetzt beschrittene Weg hat zwar Stolpersteine, führt mich aber zu dem Ergebnis, das ich brauche.
    Dass das ziemlich hemdsärmelig ist, dessen bin ich mir aber bewusst ...
    Hab einen schönen Sonntag!
    Gruß
    Dimo

    Leave a comment:


  • Christian Marquardt
    replied
    Das ist die denkbar schlechteste Lösung
    "kann ich ja auf die einzelnen Elemente und Attribute des XML zugreifen."
    Mit großem Verlust an Performance und Gewinn an komplexen SQL-Abfragen

    Leave a comment:


  • Dimo Tabken
    replied
    Guten Morgen Martin!
    Vielen Dank für Deinen Denkanstoß! Ich habe sqlxmlbulkload nun ad acta gelegt und importiere nun einfach das gesamte XML in eine entsprechende Spalte in meiner DB-Tabelle.
    In den SQL-Abfragen, die ich dann später für meine Analyse brauche, kann ich ja auf die einzelnen Elemente und Attribute des XML zugreifen.
    Das scheint für mir die unaufwändigste Lösung zu sein und reicht mir erstmal.
    Dein Tipp hat mir aber die Augen geöffnet, so kann ich weitermachen.

    Hab nochmal vielen Dank und mach Dir einen gemütlichen Sonntag!

    Gruß
    Dimo

    Leave a comment:


  • Martin Honnen
    replied
    Mit OPENXML ginge etwa

    Code:
    INSERT INTO DBName.dbo.DocMeta
    SELECT *  
    FROM   OPENXML (@idoc, '/Document')   
             WITH (DocumentID       int         'Fields/DocumentId',
                   FileID  int 'Files/File/@ID',
                   DocName   nvarchar(100)    'Files/File/@Name',
                   DocSize      int         'Files/File/@Size',
                   MimeType nvarchar(100)         'Files/File/@MimeType');

    Leave a comment:


  • Martin Honnen
    replied
    Ich bin mir nicht sicher, ob SQLXMLBulkLoad das richtige Tool ist, insbesondere weil die Daten für eine Tabellenzeile in zwei verschiedenen Unterunterelementen "DocumentID" und "File" sitzen. Ich denke, mit https://docs.microsoft.com/en-us/sql...l-server-ver15 wird man das laden können, aber bei SQLXMLBulkLoad bin ich mir nicht sicher, ob das geht. Ansonsten, aus einer Programmiersprache heraus, sollte man bei solch kleinen XML-Dateien auch keine Probleme haben, per DOM mit MSXML oder XmlDocument in .NET oder XML LINQ eine Baumstruktur eines einzelnen Dokumentes einzulesen, dann per XPath oder LINQ die entsprechenden Werte auszulesen und dann per SQL Server API von der Sprache aus in eine Datenbank zu schreiben. SQLXMLBulkLoad braucht man ja eher, um XML-Daten einzulesen, bei der auf Grund der Größe gerade keine DOM oder andere Baumstruktur geladen werden kann.

    Leave a comment:


  • Dimo Tabken
    replied
    Alles klar, dank Dir für Deine Zeit, Christian!

    Leave a comment:


  • Christian Marquardt
    replied
    Nein, sorry, da
    - gleich Zeit für Heia ist
    - ich keine Lust habe mich in VBScript einzulesen
    - ich nicht nachvollziehen kann, warum eine DB-Verbindung mit XML hergestellt wird

    Vielleicht hat Martin da weitere Infos

    Leave a comment:


  • Dimo Tabken
    replied
    OK ... Hättest Du Zeit und Lust, in #3 nochmal reinzuschauen und hast evtl. einen Tipp für mich, was ich falsch mache?
    Das wäre wirklich klasse.

    Leave a comment:


  • Christian Marquardt
    replied
    Dann bleib bei deinem Weg mit XML

    Leave a comment:


  • Dimo Tabken
    replied
    Ja, das ist absolut ein Argument, da gebe ich Dir recht.
    Plan für die Zukunft ist das sicherlich, aber jetzt muss ich's halt irgendwie hinbiegen und mir fehlt die Zeit, mich erst in eine richtige Programmiersprache einzuarbeiten. Muss also zwangsläufig mit dem Arbeiten, was ich kann und habe :-(

    Leave a comment:


  • Christian Marquardt
    replied
    Nein, aber solange das einmaliger Vorgang ist, dauert es halt solange wie es dauert.
    Und es wäre an der Zeit das mit einer richtigen Programmiersprache zu tun. VBScript ist eine tote Sprache.

    Leave a comment:


  • Dimo Tabken
    replied
    OK, neuer Gedankenansatz, den ich noch nicht kenne, Christian. Ich hatte den Eindruck gewonnen, dass das über den ersten Weg der erfolgversprechendste Ansatz wäre.

    hast Du eine Idee, welcher der Beiden Wege der Performantere sein würde? Bei *dieser* Menge XML-Dateien wird ja auch das eine Rolle spielen ...

    Leave a comment:


  • Christian Marquardt
    replied
    Warum muss das kompliziert über XML laufen?
    XML-Datei öffnen
    XML parsen
    insert Statement mit den 5 Feldern
    Nächste Datei

    Leave a comment:


  • Dimo Tabken
    replied
    Hallo Martin!
    Ja, jedes XML-Dokument hat immer nur ein "Document"-Element.
    Jedes XML-Dokument gehört in eine Zeile der SQL-DB.
    Die 1,5 Mio. Dateien in die Datenbank zu überführen, ist leider gerade exakt meine Aufgabenstellung :-) Daher bin ich gerade am Wühlen, wie ich das hinbekomme.

    Zu Deiner Frage nach einem Beispiel:

    Die folgenden Zuordnungen brauche ich:
    Datenbank SQL-Element
    DocumentID Der DocID-Wert (437445) aus <DocumentID>
    FileID Attribut ID="0001" von <File>
    DocName Attribut Name="IrgendEinDocName.doc" von <File>
    DocSize Attribut Size="55296" von <File>
    MimeType Attribut MimeType="application/octet-stream" von <File>
    Weitere Werte brauche ich für die Übernahme nicht. Was sonst noch an Werten in der XML steht, kann ich ignorieren.

    Macht es das für Dich nachvollziehbarer?

    Leave a comment:

Working...
X