Glengamoi (Forum) · AspHeute · .NET Heute (RSS-Suche) · AspxFiles (Wiki) · .NET Blogs
ASP German Homepage Homepage
 

Liste

.NET 2.0 (1)
.NET Allgemein (16)
.NET Fu (5)
ADO.NET (11)
Aprilscherz (3)
ASP Grundlagen (44)
ASP Tricks (83)
ASP.NET (44)
ASPIntranet.de (5)
C# (28)
Datenbank (44)
Dokumentation (4)
IIS 6.0 (1)
Komponenten (29)
Optimierung (10)
Server (21)
Sicherheit (34)
Tee Off (6)
VB.NET (6)
WAP (8)
Web Services (11)
XML (9)

RSS 2.0 - Die neuesten fünf Artikel auf AspHeute.com


 

Suchen





 

English Articles
Chinese Articles
Unsere Autoren
 
Link zu AspHeute
Impressum
Werben
Anfragen

Daten aus CSV-Dateien in MDBs importieren

Geschrieben von: Christian Holm
Kategorie: Datenbank

Manchmal stellt sich einem die Aufgabe, Datenbanksysteme aus irgendwelchen Gründen zu wechseln. Die Daten müssen transferiert werden - und als kleinster gemeinsamer Nenner zwischen den Systemen bleibt meist nur das CSV Format. Dieser Artikel zeigt einen von vielen Wegen um eine CSV-Datei in eine Access Datenbank zu konvertieren - und das, ohne daß Access installiert sein muß.

Wie Sie sicher schon aus der Überschrift entnehmen konnten, zeige ich Ihnen heute den umgekehrten Weg den der Artikel CSVs aus MDBs leicht gemacht beschrieben hat. Abermals habe ich eine VBScript Klasse geschrieben, um den Konvertierungsvorgang zu vollziehen. Man kann damit leicht den Vorgang automatisieren und das Script läßt auch einige Konfigurationsoptionen zu.

Beginnen wir also gleich mit der Klasse CSV2MDB, die den Konvertierungsvorgang vollzieht, und in der CSV2MDB.Class.asp Datei zu finden ist.

Class CSV2MDB

    Public FirstLineContainsFieldNames
    Public UseTextQualifier
    Public CreateNewDB
    Public TableExists
    
    Public Sub ConvertToMDB(ByVal strMDBPath, ByVal strTableName, _
                            ByVal strCSVPath, ByVal strCSVFileName)
    
    Const ForReading = 1
    Const ForWriting = 2
    
    strDB = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strMDBPath

Zuerst werden einige Properties deklariert, mit denen man das Objekt leicht an die speziellen Wünsche anpassen kann. Die Properties nehmen die Werte true oder false an. Mit der FirstLineContainsFieldNames Property können Sie angeben, ob die erste Zeile der CSV-Datei die Spaltennamen der Datentabelle enthält. Mit der entsprechenden Angabe von UseTextQualifier signalisieren Sie die Verwendung von doppelten Anführungszeichen als zusätzliche Spaltenbegrenzer. Diese Formatierung ist besonders dann nützlich, wenn Datensätze Beistriche etc. verwenden, die als Delimiter mißinterpretiert werden könnten.

Die CreateNewDB Property bietet die Möglichkeit eine neue Datenbank für die Importdaten anlegen zu lassen. Diese Datenbank kann entweder im selben Verzeichnis, wo das Script ausgeführt wurde, abgelegt werden oder in einem beliebigen Pfad gespeichert werden. Diese Pfadinformationen werden der strMDBPath Variable entnommen, die der ConvertToMDB Sub-Prozedur als Parameter übergeben wird. (Die ConvertToMDB Sub-Prozedur enthält die Konvertierungsfunktionalität in mdb-Dateien.)

Die letzte Property ist TableExists. Falls diese Property auf true gesetzt wurde, wird eine eventuell schon vorhandene Tabelle gleichen Namens gelöscht. Dieser Fall tritt nur dann ein, wenn auf die Erstellung einer neuen Access Datenbank verzichtet wurde (CreateNewDB = false).

Zusätzlich zu den oben besprochenen Parametern, die der ConvertToMDB Sub-Prozedur übergeben werden müssen, muß noch der Pfad, wo sich die CSV-Datei befindet (strCSVPath) und ihr Dateiname (strCSVFileName) angegeben werden. Die beiden angeführten Konstanten ForReading und ForWriting werden in einem späteren Abschnitt des Sourcecodes für die Dateioperationen mit dem FileSystemObject benötigt. Die strDB Variable enthält die für eine Access Datenbank benötigten Providerinformationen und den Pfad zu dieser. Diese Variable wird entweder für die Erstellung einer neuen Datenbank oder zur Öffnung der Verbindung zu einer bestehenden Datenbank benötigt.

Da die Erstellung einer neuen Access Datenbank unabhängig von Access geschehen soll, verwenden wir ADOX (Microsoft ADO Extensions for DDL and Security) um dies zu erledigen:

If (CreateNewDB) Then
    Set objNewCatalog = Server.CreateObject("ADOX.Catalog") 
    objNewCatalog.Create strDB
    Set objNewCatalog = Nothing
End If

Da nur eine neue Datenbank erstellt werden soll, wenn auch die CreateNewDB auf true gesetzt ist, verwenden wir hier eine If-Verzweigung. Da die strDB in Kombination mit dem übergebenen Parameter strMDBPath alle Informationen für einen Datenbank enthält, können wir also mit der Create Methode eine neue erstellen. Diese wird gemäß den Pfadangaben der strMDBPath Variable angelegt.

Falls in einer vorhandenen Datenbank bereits eine Tabelle gleichen Namens existiert, löscht die folgende Anweisung mittels DROP diese:

If (TableExists) Then  
    Set objDropTableConn = Server.CreateObject("ADODB.Connection")
    objDropTableConn.Open strDB
    objDropTableConn.Execute "DROP TABLE " & strTableName
    objDropTableConn.Close
    Set objDropTableConn = Nothing
End If   

Nun sind wir soweit, daß wir eine neue Tabelle in der bereits existierenden bzw. neu erstellten Datenbank erstellen können. Dies geschieht wiederum mit Hilfe von ADOX:

Set objCatalog = Server.CreateObject("ADOX.Catalog")
    objCatalog.ActiveConnection = strDB
    Set objTable = Server.CreateObject("ADOX.Table")
    Set fso = Server.CreateObject("Scripting.FileSystemObject")
    objTable.Name = strTableName
    objCatalog.Tables.Append objTable

    Set CVSFile = fso.OpenTextFile(strCVSFileFullPath, ForReading)
    strFields = CVSFile.ReadLine
    CVSFile.Close
    Set CVSFile = Nothing
    Set fso = Nothing

Zusätzlich treffen wir eine Vorbereitung für die Erstellung der Spaltennamen. Hier wird die erste Zeile (ReadLine Methode des FileSystemObjects) der mit den Variablen strCSVPath und strCSVFileName angegebenen CSV-Datei eingelesen. Diese Information, welche in der strFields Variable abgelegt ist, wird später entweder für die Feldnamen selbst, oder für die Bestimmung der Spaltenanzahl verwendet.

Als nächstes schreiben wir die Spaltenüberschriften in die neu erstellte Tabelle. Hier gibt es wie schon erwähnt zwei Möglichkeiten: entweder entspricht die erste Zeile der CSV-Datei den Spaltenüberschriften oder nicht. Die erste Zeile der CSV-Dateien haben wir ja schon in der strFields gespeichert und können nun per Split Funktion den String in die einzelnen Spalten aufteilen und jede einzelne der Tabelle als Überschrift zuweisen.

Hier tritt wieder der Fall ein, daß man überprüfen muß, ob die Spalten doppelte Anführungszeichen als zusätzliche Delimiter haben. Wenn ja, dann werden diese mit der Replace Funktion entfernt:

If (FirstLineContainsFieldNames) Then
    If (UseTextQualifier) Then
        strFields = Replace(strFields, """","")
    End If    
    
    arFields = Split(strFields,",")
    
    For Each item In arFields
       objTable.Columns.Append item
    Next    
Else
    arFields = Split(strFields,",")
    nCount = 0
    
    For Each item In arFields
       nCount = nCount + 1
       objTable.Columns.Append "Field" & nCount
    Next
End If    

Wenn aber die erste Zeile in der CSV-Datei nicht die Spaltenüberschriften enthält, schreiben wir Standardwerte mit einer fortlaufenden Nummer als Überschriften. Die fortlaufende Nummer wird durch die Anzahl der Substrings des Arrays arFields bestimmt. Die neu generierten Standardüberschriften, die sich nachträglich ändern lassen, da ja keine Beziehungen zu anderen Tabellen existieren, werden wiederum mit Hilfe der ADOX Methode Append den Spalten zugewiesen.

Jetzt können wir endlich die Daten aus der CSV-Datei in die Access Datenbank importieren. Da standardmäßig für Access immer die erste Zeile einer CSV-Datei als Spaltenüberschriften herangezogen wird, müssen wir im Fall, daß keine angegeben wurden und welche generiert werden mußten, ein wenig tricksen. Es sollen ja weder die erste Zeile, welche die eigentlichen Daten enthält als Überschrift verwendet werden, noch Komplikationen während des Einfügens der Daten per SQL Statement auftreten.

Wir erstellen uns also mit dem FileSystemObject eine temporäre Datei (temp.csv), die in der ersten Zeile unsere vorher generierten Überschriften enthält. Nach diesem Eintrag werden dann die eigentlichen Daten aus der ursprünglichen CSV-Datei mittels der ReadAll Methode des FileSystemObjects eingefügt. Weiters ist hier wieder auf die Möglichkeit der zusätzlichen Delimiter zu achten, damit die ersten Felder korrekt formatiert werden:

If Not (FirstLineContainsFieldNames) Then
    Set objFSO = Server.CreateObject("Scripting.FileSystemObject")
    Set objTempFile = objFSO.OpenTextFile(strCSVPath & "temp.csv", ForWriting, True)
    
    If (UseTextQualifier) Then
        For n=1 To nCount
            objTempFile.Write """Field" & n
            If n <> nCount Then
                objTempFile.Write ""","
            End If  
        Next
    Else
        For n=1 To nCount
            objTempFile.Write "Field" & n
            If n <> nCount Then
                objTempFile.Write ","
            End If
        Next
    End If
    
    objTempFile.Write """"
    objTempFile.WriteBlankLines(1)
    
    Set CVSFile = objFSO.OpenTextFile(strCVSFileFullPath, ForReading)
    strCVSContent = CVSFile.ReadAll
    CVSFile.Close
    Set CVSFile = Nothing
    
    objTempFile.Write strCVSContent
    objTempFile.Close

Nun da diese temporäre Datei erfolgreich erstellt wurde, können wir mit einem angepaßten SQL Statement die Daten aus dieser Datei in unsere Tabelle einfügen:

strSQLAlt = "INSERT INTO " & strTableName & " SELECT * FROM [temp.csv"
strSQLAlt = strSQLAlt &  "] IN """ & strCSVPath & """ ""TEXT;"""

objConn.Execute strSQLAlt

Set objTempFile = objFSO.GetFile(strCSVPath & "temp.csv")
objTempFile.Delete

Da wir nun die Temporärdatei nicht mehr benötigen, wird sie am Schluß wieder gelöscht. Die Alternative (Spaltenüberschiften in der ersten Zeile) ist um einiges weniger aufwendig. Hier reicht das Einfügen der Daten aus der mit strCSVPath und strCSVFileName angegebenen CSV-Datei mittels SQL Statement. Dieses ist in der Variable strSQL enthalten:

strSQL = "INSERT INTO " & strTableName & " SELECT * FROM [" & strCSVFileName
strSQL = strSQL &  "] IN """ & strCSVPath & """ ""TEXT;"""

objConn.Execute strSQL

Als Abschluß möchte ich noch die zwei möglichen Hauptvarianten in Form von Beispielscripts präsentieren. Zunächst nehmen wir an, daß die CSV-Datei in der ersten Zeile die Datenspaltenüberschrift enthält. Für diesen Fall wäre dieser Sourcecode in Verbindung mit der besprochenen VBScript Klasse notwendig (TestDrive.asp):

<!-- #include file="CSV2MDB.Class.asp" --> 

<%
    Dim objCSV2MDB
    Set objCSV2MDB = New CSV2MDB
    
    strMDBPath = Server.MapPath("csv2mdb.mdb")
    strTableName = "tProducts"
    strCSVPath = Server.MapPath("./") & "\"
    strCSVFileName ="test.csv"
    objCSV2MDB.FirstLineContainsFieldNames = true
    objCSV2MDB.UseTextQualifier = true
    objCSV2MDB.CreateNewDB = true
    objCSV2MDB.TableExists = false
    objCSV2MDB.ConvertToMDB strMDBPath, strTableName, strCSVPath, strCSVFileName
    
    Set objCSV2MDB = Nothing
%>

Zuerst wird die CSV2MDB.Class.asp ASP-Datei, welche die Klasse enthält, per include-Anweisung eingebunden. Danach ist ein neues Objekt mit der Referenz zu der VBScript Klasse zu instanzieren. Weiters sind den der Sub-Prozedur zu übergebenden Parametern entsprechende Werte zuzuweisen, und die Properties des Objektes zu setzen. Schließlich und endlich erfolgt der Aufruf der Prozedur mit der Übergabe der Parameter - fertig.

Die verwendete Beispiel-CSV-Datei sieht wie folgt aus:

Das Ergebnis - die Access Datenbank - sieht nach erfolgreicher Erstellung aus der CSV-Datei so aus:

Für den Fall, daß keine Spaltenüberschriften vorhanden sind, sind im Beispielscript TestDrive.asp folgende Änderungen in der Zeile, die die FirstLineContainsFieldNames Property enthält, durchzuführen:

objCSV2MDB.FirstLineContainsFieldNames = false

Dies ergibt bei entsprechender CSV-Datei folgendes Ergebnis:

Natürlich sind dann im Einsatz des Scriptes die Properties und Pfadeinstellungen ensprechend dem Anwendungsfall anzupassen.

Schlußbemerkung

Das gezeigte Beispiel läßt sich wie Sie sicherlich erkannt haben, leicht an den Anwendungsfall anpassen und vor allem z.B. für mehrere Dateien automatisieren. Zwar gehen bei einem solchen Konvertierungsvorgang alle Relationships zwischen den Tabellen oder auch anderen externen Datenbanken verloren, diese sind aber meist einfacher und schneller wieder herzustellen als die Datensätze.

Download des Codes

Klicken Sie hier, um den Download zu starten.

Verwandte Artikel

CSVs aus MDBs leicht gemacht
Klassen in VBScript
Tabellenerstellung mit ADOX
Yet Another Access Database Administration Tool

Wenn Sie jetzt Fragen haben...

Wenn Sie Fragen rund um die in diesem Artikel vorgestellte Technologie haben, dann schauen Sie einfach bei uns in den Community Foren der deutschen .NET Community vorbei. Die Teilnehmer helfen Ihnen gerne, wenn Sie sich zur im Artikel vorgestellten Technologie weiterbilden möchten.

Haben Sie Fragen die sich direkt auf den Inhalt des Artikels beziehen, dann schreiben Sie dem Autor! Unsere Autoren freuen sich über Feedback zu ihren Artikeln. Ein einfacher Klick auf die Autor kontaktieren Schaltfläche (weiter unten) und schon haben Sie ein für diesen Artikel personalisiertes Anfrageformular.

 

Und zu guter Letzt möchten wir Sie bitten, den Artikel zu bewerten. Damit helfen Sie uns, die Qualität der Artikel zu verbessern - und anderen Lesern bei der Auswahl der Artikel, die sie lesen sollten.

Bewerten Sie diesen Artikel
 Sehr gut   Nicht genügend  
   1  2  3  4  5  
 

  
   Für Ausdruck optimierte Seite

©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.