Discussion:
SCHEMA.INI programmintern?
(zu alt für eine Antwort)
Peter Tübben
2005-10-14 11:43:24 UTC
Permalink
Hallo,

ich verarbeite CSV-Dateien unterschiedlicher Herkunft. Es gibt
Semikolon-separierte aber auch Komma-separierte CSV-Dateien. Ich weiss
vorher, welcher Separator mich da erwartet und schreibe eine
entsprechende SCHEMA.INI auf die Platte, damit ich mit meiner
OleDbConnection auf die CSV-Datei zugreifen kann.

Nun frage ich mich (und hiermit natürlich auch Euch), ob man die
Konfigurierung meiner Connection nicht auch programmintern vornehmen
kann, damit ich nicht immer vor dem Datenzugriff die SCHEMA.INI
speichern muss.

Danke im voraus & Grüße ... Peter
Peter Fleischer
2005-10-14 12:38:42 UTC
Permalink
"Peter T�bben" <***@nurfuerspam.de> schrieb im Newsbeitrag news:e$RR%***@TK2MSFTNGP09.phx.gbl...
..
Post by Peter Tübben
ich verarbeite CSV-Dateien unterschiedlicher Herkunft. Es gibt
Semikolon-separierte aber auch Komma-separierte CSV-Dateien. Ich weiss
vorher, welcher Separator mich da erwartet und schreibe eine
entsprechende SCHEMA.INI auf die Platte, damit ich mit meiner
OleDbConnection auf die CSV-Datei zugreifen kann.
Nun frage ich mich (und hiermit natürlich auch Euch), ob man die
Konfigurierung meiner Connection nicht auch programmintern vornehmen
kann, damit ich nicht immer vor dem Datenzugriff die SCHEMA.INI
speichern muss.
Peter,
das geht schon intern, nur musst du dann auf die Standardfunktionalität der
Jet verzichten und die Daten-Datei mit den einfachen Datei-Lese-Methoden
einlesen und im lokalen Datenspeicher (z.B. DataSet) incl. Konvertierung
ablegen. Der Aufwand, so etwas zu programmieren, ist nicht besonders hoch.

Peter
Peter Tübben
2005-10-14 14:11:24 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
das geht schon intern, nur musst du dann auf die
Standardfunktionalität der
Post by Peter Fleischer
Jet verzichten und die Daten-Datei mit den einfachen
Datei-Lese-Methoden
Post by Peter Fleischer
einlesen und im lokalen Datenspeicher (z.B. DataSet) incl.
Konvertierung
Post by Peter Fleischer
ablegen.
Du meinst, die CSV-Datei mit einem StreamReader.ReadLine zeilenweise
einzulesen, die Felder dann mit einer geeigneten Methoden
auseinanderdröseln und sie dann in ein Dataset zu füllen?

Nun, dass ist zufälligerweise auch meine momentane Vorgehensweise ;-)
Da ich aber denke, dass das Einlesen mit OleDb ein wenig
professioneller ist, möchte ich zukünftig gerne diese Technik
verwenden, zumal ich mir dann keine grossartigen Gedanken darum machen
muss, ob in den Feldern selber ein Trennzeichen vorkommt.
Post by Peter Fleischer
Der Aufwand, so etwas zu programmieren, ist nicht besonders hoch.
das ist Ansichtssache ;-)

Kannst Du die Vorgehensweise vielleicht ein wenig genauer erklären?

Danke im voraus & Grüße ... Peter
Peter Fleischer
2005-10-14 22:05:48 UTC
Permalink
Peter Tübben wrote:
...
Post by Peter Tübben
Du meinst, die CSV-Datei mit einem StreamReader.ReadLine zeilenweise
einzulesen, die Felder dann mit einer geeigneten Methoden
auseinanderdröseln und sie dann in ein Dataset zu füllen?
Peter,
na klar: ReadLine, Split, ItemArray - in VB.NET nur wenige Zeilen Code.
Post by Peter Tübben
Nun, dass ist zufälligerweise auch meine momentane Vorgehensweise ;-)
Da ich aber denke, dass das Einlesen mit OleDb ein wenig
professioneller ist, möchte ich zukünftig gerne diese Technik
verwenden, zumal ich mir dann keine grossartigen Gedanken darum machen
muss, ob in den Feldern selber ein Trennzeichen vorkommt.
Doppelte Begrenzerzeichen durch einfache zu ersetzen ist nun wirklich kein
kompliziertes Problem. Ich habe jetzt keine Regex-Lösung parat, kann mir
aber vorstellen, dass das recht einfach ist.
Post by Peter Tübben
Post by Peter Fleischer
Der Aufwand, so etwas zu programmieren, ist nicht besonders hoch.
das ist Ansichtssache ;-)
Kannst Du die Vorgehensweise vielleicht ein wenig genauer erklären?
s. oben:

Zeilenweises Einlesen, Split mit Berücksichtigung doppelter Begrenzer,
Konvertierung, Zuweisen ItemArray!

Peter
Immo Landwerth
2005-10-15 21:14:29 UTC
Permalink
Post by Peter Fleischer
...
Post by Peter Tübben
Du meinst, die CSV-Datei mit einem StreamReader.ReadLine zeilenweise
einzulesen, die Felder dann mit einer geeigneten Methoden
auseinanderdröseln und sie dann in ein Dataset zu füllen?
Peter,
na klar: ReadLine, Split, ItemArray - in VB.NET nur wenige Zeilen Code.
Es sei nur kurz angemerkt, dass in CSV-Dateien ein CR/LF nicht
zwangsweise ein Datensatztrenner darstellt.

Die folgenden drei Zeilen z.B. gelten als ein Datensatz:

"ID";"Name";"Kommentar"
"ABC";"CSV-Dateien";"Das ist ein Text der ein
CR/LF enthält"

Es ist zwar keine Hexerei CSV Dateien einzulesen, aber ich habe leider
schon zu viele halb gare Lösungen in der Praxis erlebt :-)
--
Immo Landwerth - Visual Studio 2003 - C# - XanaNews 1.17.5.7
Peter Fleischer
2005-10-15 21:25:56 UTC
Permalink
Immo Landwerth wrote:
...
Post by Immo Landwerth
Es ist zwar keine Hexerei CSV Dateien einzulesen, aber ich habe leider
schon zu viele halb gare Lösungen in der Praxis erlebt :-)
Immo,
deshalb bin ich - auch wenn der Aufwand etwas größer ist - für eine eigene
Lösung, die sequetiel Byte für Byte einliest uns zwischen den
Begrenzerzeichen den Text pre übernimmt ausgenommen verdoppelte
Bergenzereichen. Nach meiner Erfahrung macht so etwas die Jet nur mit
CSV-Dateien, die in jeder Spalte eindeutige gleicheartige Texte haben, die
sich zum vorgegeben oder implizit ermittelten Typ konvertieren lassen.

Peter
Peter Fleischer
2005-10-15 21:44:53 UTC
Permalink
...
Post by Immo Landwerth
Es ist zwar keine Hexerei CSV Dateien einzulesen, aber ich habe
leider schon zu viele halb gare Lösungen in der Praxis erlebt :-)
Immo,
es ist schon späte und man sollte vielleicht schlafen gehen bei den vielen
Rechtschreibfehlern. Hor nochmals korrigiert:

Deshalb bin ich - auch wenn der Aufwand etwas größer ist - für eine
eigene Lösung, die sequentiell Byte für Byte einliest und zwischen den
Begrenzerzeichen den Text unverändert übernimmt, ausgenommen verdoppelte
Begrenzerzeichen. Nach meiner Erfahrung macht so etwas die Jet nur mit
CSV-Dateien, die in jeder Spalte eindeutige gleichartige Texte haben, die
sich zum vorgegebenen oder implizit ermittelten Typ konvertieren lassen.

Peter
Immo Landwerth
2005-10-17 08:33:04 UTC
Permalink
Post by Peter Fleischer
...
Post by Immo Landwerth
Es ist zwar keine Hexerei CSV Dateien einzulesen, aber ich habe
leider schon zu viele halb gare Lösungen in der Praxis erlebt :-)
Immo,
es ist schon späte und man sollte vielleicht schlafen gehen bei den
Kein Problem :-)
Post by Peter Fleischer
Deshalb bin ich - auch wenn der Aufwand etwas größer ist - für eine
eigene Lösung, die sequentiell Byte für Byte einliest und zwischen
den Begrenzerzeichen den Text unverändert übernimmt, ausgenommen
verdoppelte Begrenzerzeichen. Nach meiner Erfahrung macht so etwas
die Jet nur mit CSV-Dateien, die in jeder Spalte eindeutige
gleichartige Texte haben, die sich zum vorgegebenen oder implizit
ermittelten Typ konvertieren lassen.
Aus letzten Satz entnehme ich, dass das folgende zu Problemen führt:

"ID";"Value"
"2";"19.10.2005"
"A";"Immo"

Weil die Jet Engine in der zweiten Zeile jeweils die Datentypen INT und
DATE ableitet und das in der dritten Zeile dann kräftig knallt. Sehe
ich das richtig?

Nun, in diesem Fall würde ich Dir zustimmen. Da führt das selbst
gebraute sicherlich zu einem besseren Bier. :-)
--
Immo Landwerth - Visual Studio 2003 - C# - XanaNews 1.17.5.7
Elmar Boye
2005-10-15 08:35:07 UTC
Permalink
Hallo Peter,
Post by Peter Tübben
ich verarbeite CSV-Dateien unterschiedlicher Herkunft. Es gibt
Semikolon-separierte aber auch Komma-separierte CSV-Dateien. Ich weiss
vorher, welcher Separator mich da erwartet und schreibe eine
entsprechende SCHEMA.INI auf die Platte, damit ich mit meiner
OleDbConnection auf die CSV-Datei zugreifen kann.
Nun frage ich mich (und hiermit natürlich auch Euch), ob man die
Konfigurierung meiner Connection nicht auch programmintern vornehmen
kann, damit ich nicht immer vor dem Datenzugriff die SCHEMA.INI
speichern muss.
Die Jet kennt prinzipiell drei Wege.

Einmal die SCHEMA.INI. Die ist am variabelsten und das "modernste"
was die Jet hat.

Dann eine direkte Angabe in der SQL Anweisung:
SELECT ... FROM
[Text;FMT=Delimited;HDR=YES;CharacterSet=ANSI;DATABASE=C:\PFADE;].TEST#TXT

das ist die älteste Variante aus Access 1.X/2.0 Zeiten und ermöglicht
nur eine relativ grobe Angabe von Trennformat, Zeichensatz und ob mit
Spaltenüberschriften. Die möglichen Angaben entsprechen denen der SCHEMA.INI
Sie sind allerdings m. W. nie vollständig dokumentiert worden.

Und zuletzt eine über die internen Format-Spezifikationen anhand
zweier interner Tabellen. Die sind allerdings Access-Spezifisch
und durch die SCHEMA.INI für die Treiber unabhängig von Access
geworden. Ich würde sie programmatisch nicht einsetzen.

Letztendlich ist die SCHEMA.INI immer noch das einfachste.
Selbstgebaute Treiber brauchen letztendlich etwas wenns über
Standardannahmen hinausgeht. .NETtiger Weg wäre dabei, die
Schema.ini über eine Handvoll Klassen abzubilden.

Zu Deiner Diskussion mit Peter, ob man es selbst machen kann:
Sicher kann man. Nur ist es schon aufwändiger, die Fehlertoleranz
und Geschwindigkeit der Jet Treiber zu erreichen.

Gruss
Elmar
Peter Fleischer
2005-10-15 09:37:28 UTC
Permalink
Elmar Boye wrote:
...
Post by Elmar Boye
Sicher kann man. Nur ist es schon aufwändiger, die Fehlertoleranz
und Geschwindigkeit der Jet Treiber zu erreichen.
Aus meiner persönlichen Erfahrung funktioniert stabil mit der Jet und der
schema.ini nur die Variante mit der Semikolontrennung. Bei allen anderen
Varianten hatte ich immer irgenwo Probleme. Das beginnt schon mit den
Dateiendungen, die in früheren Versionen der Jet frei wählbar waren, mit der
Jet 40 aber recht begrenzt sind. Das geht dann weiter mit Formatierungen der
Strings in der Datei, wenn andere Formate als String im Ziel benötigt werden
und ein Typkonvertierung erfordern. Und es endet mit Standardannahmen, wenn
die Feldinhalte leer sind und/oder in der achema.ini keine oder unpassende
Einträge zu den betreffenden Spalten stehen. Unpassende Einträge können zu
DBNull ohne Fhlerinformation und damit zu Datenverlust führen. Es ist also
alles recht speziell und funktioniert bei mir nur problemlos, wenn ich
strikt die Standardannahmen nutze: Semikolon als Feldtrenner, amerikanische
Stringdarstellung, alle Felder mit genau passendem Inhalt.

Peter
Elmar Boye
2005-10-15 15:36:16 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
...
Post by Elmar Boye
Sicher kann man. Nur ist es schon aufwändiger, die Fehlertoleranz
und Geschwindigkeit der Jet Treiber zu erreichen.
Aus meiner persönlichen Erfahrung funktioniert stabil mit der
Jet und der schema.ini nur die Variante mit der Semikolontrennung.
Dafür brauchst Du die gar nicht, solange Dir die Feldnamen
egal und die Datentypen Jet geraten reichen, da reicht die
gezeigt SQL Variante.
Post by Peter Fleischer
Das beginnt schon mit den Dateiendungen, die in früheren Versionen
der Jet frei wählbar waren, mit der Jet 40 aber recht begrenzt sind.
Lässt sich via Registry ändern - wobei eine Datei umbenennen
einfacher ist.
Post by Peter Fleischer
Das geht dann weiter mit Formatierungen der Strings in der Datei,
wenn andere Formate als String im Ziel benötigt werden und ein
Typkonvertierung erfordern.
Lässt sich anpassen... siehe Beschreibung in der JETSQL40.CHM
(bei Office 200x).

Generell gilt nun, exotische Formate machen immer Ärger.
Das gälte ebenso für jede eigenprogrammierte Lösung. Da kommt
schon einiges mehr zusammen als ReadLine, Split, ItemArray ;-)
Post by Peter Fleischer
Unpassende Einträge können zu DBNull ohne Fhlerinformation
und damit zu Datenverlust führen.
wovor eigengestrickte Lösung genausowenig gefeit sind.

Am Ende: Ein eigengeschriebener Treiber, der nur die Möglichkeiten
des Jet Text-Treibers bieten soll, kostet zumindest einige Tage
an Programmierung... Und bis alle Fehlerteufelchen rausgeworfen
sind...

Gruss
Elmar
Peter Fleischer
2005-10-15 16:28:20 UTC
Permalink
Elmar Boye wrote:
...
Post by Elmar Boye
Post by Peter Fleischer
Aus meiner persönlichen Erfahrung funktioniert stabil mit der
Jet und der schema.ini nur die Variante mit der Semikolontrennung.
Dafür brauchst Du die gar nicht, solange Dir die Feldnamen
egal und die Datentypen Jet geraten reichen, da reicht die
gezeigt SQL Variante.
Elmar,
das ist schon klar. Wenn ich aber in der schema.ini angebe:

Format=Tabdelimited

dann habe ich Probleme eine Datei mit Endung CSV sauber einzulesen.
Post by Elmar Boye
Post by Peter Fleischer
Das beginnt schon mit den Dateiendungen, die in früheren Versionen
der Jet frei wählbar waren, mit der Jet 40 aber recht begrenzt sind.
Lässt sich via Registry ändern - wobei eine Datei umbenennen
einfacher ist.
Auch das habe ich mit recht zweifelhaften Erfolg probiert. Einigermaßen
venüftige Ergebnisse habe ich ohne Änderungen mit der Endung TXT und CSV
erhalte, wobei bei CSV andere Trennzeichen als Semikolon wieder Probleme
bringen, auch wenn die Datei zur schema.ini passen.
Post by Elmar Boye
Post by Peter Fleischer
Das geht dann weiter mit Formatierungen der Strings in der Datei,
wenn andere Formate als String im Ziel benötigt werden und ein
Typkonvertierung erfordern.
Lässt sich anpassen... siehe Beschreibung in der JETSQL40.CHM
(bei Office 200x).
Hast du das mal mit Datumsdarstellungen probiert?
Post by Elmar Boye
Generell gilt nun, exotische Formate machen immer Ärger.
Das kann ich nur fett bestätigen!
Post by Elmar Boye
Das gälte ebenso für jede eigenprogrammierte Lösung. Da kommt
schon einiges mehr zusammen als ReadLine, Split, ItemArray ;-)
Wenn die exotische Darstellung in sich schlüssig ist, d.h. alle Daten auch
wirklich durchgängig in der Spalte im festgelegten exotischen Format
vorliegen, dann ist eine eigene Lösung schneller zusammengestellt als die
endlosen Versuche mit den Einstellungen in der schema.ini und den
Dateiendungen.
Post by Elmar Boye
Post by Peter Fleischer
Unpassende Einträge können zu DBNull ohne Fhlerinformation
und damit zu Datenverlust führen.
wovor eigengestrickte Lösung genausowenig gefeit sind.
Das stimmt natürlich.
Post by Elmar Boye
Am Ende: Ein eigengeschriebener Treiber, der nur die Möglichkeiten
des Jet Text-Treibers bieten soll, kostet zumindest einige Tage
an Programmierung... Und bis alle Fehlerteufelchen rausgeworfen
sind...
Peter Tübben wollte aber die Jet als eierlegende Wollmilchsau nutzen:-) Und
das geht bestimmt nur mit Problemen.

Peter
Elmar Boye
2005-10-16 09:36:35 UTC
Permalink
Hallo Peter,
Post by Peter Fleischer
Post by Elmar Boye
Post by Peter Fleischer
Aus meiner persönlichen Erfahrung funktioniert stabil mit der
Jet und der schema.ini nur die Variante mit der Semikolontrennung.
Dafür brauchst Du die gar nicht, solange Dir die Feldnamen
egal und die Datentypen Jet geraten reichen, da reicht die
gezeigt SQL Variante.
Format=Tabdelimited
dann habe ich Probleme eine Datei mit Endung CSV sauber einzulesen.
D. h. es immer zuerst definiere CSV.
Denn für Excel z. B. bedeutet CSV Komma/Listentrennzeichenseparaiert,
d. h. auf deutschem System mit ";" (entsprechend Ländereinstellungen).

Tabdelimited bedeutet Tabulator, und wäre bei Excel das sog.
Text (Tabstop getrennt) Format.
Post by Peter Fleischer
Post by Elmar Boye
Post by Peter Fleischer
Das beginnt schon mit den Dateiendungen, die in früheren Versionen
der Jet frei wählbar waren, mit der Jet 40 aber recht begrenzt sind.
Lässt sich via Registry ändern - wobei eine Datei umbenennen
einfacher ist.
Auch das habe ich mit recht zweifelhaften Erfolg probiert.
Einigermaßen venüftige Ergebnisse habe ich ohne Änderungen mit der
Endung TXT und CSV erhalte, wobei bei CSV andere Trennzeichen als
Semikolon wieder Probleme bringen, auch wenn die Datei zur schema.ini
passen.
Für alles was Du nicht definierst gelten die Standardannahmen
und was in der Registry unter
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Jet\4.0\Engines\Text
steht - bzw. dem im ConnectionString angegebenen Registry Pfad.

Dort findet sich auch DisabledExtensions, das die zulässigen
Dateiendungen festlegt.
Post by Peter Fleischer
Post by Elmar Boye
Post by Peter Fleischer
Das geht dann weiter mit Formatierungen der Strings in der Datei,
wenn andere Formate als String im Ziel benötigt werden und ein
Typkonvertierung erfordern.
Lässt sich anpassen... siehe Beschreibung in der JETSQL40.CHM
(bei Office 200x).
Hast du das mal mit Datumsdarstellungen probiert?
Sagen wir mal so: Ich hatte mal das zweifelhafte Vergnügen
(kein .Net sondern Office) die Texttreiber auf Datenquellen
verschiedenen Typs anzusetzen. Am "beliebtesten" waren da
bei mir solche die auf Excel-Daten basierten.
Eingesetzt habe ich da am Schluss ein (VBA)Modul, dass die
SCHEMA.INI anhand von Tabellenspezifikationen erzeugte.
Naja, und irgendein Trödel kriegte immer mal wieder einen
Fehler eingebaut, that's life ;-)

Als auch mal Access Spezi empfehle ich da, sich zunächst
den Konvertierungsassitenten von Access anzugucken.
Die Schema.ini am Ende bildet das inhaltlich ab.

Für Datumsformate gelten die Regeln von VB(A).Format.
Post by Peter Fleischer
Post by Elmar Boye
Am Ende: Ein eigengeschriebener Treiber, der nur die Möglichkeiten
des Jet Text-Treibers bieten soll, kostet zumindest einige Tage
an Programmierung...
Peter Tübben wollte aber die Jet als eierlegende Wollmilchsau
nutzen:-)
Ich habe noch nie eine Wollmilchsau gesehen ;-)
Allerdings halte ich den Texttreiber von Jet schon gut nutzbar.

Vor allem verglichen mit dem was so im .NET Umfeld so rumkreist
Viele mögen nur ihre nationalen Trennzeichen und Dezimaltrennzeichen,
Datumsformate, beim Anführungszeichen im Text kriegen sie fast
alle das Schwimmen. (Galt zumindestens Ende letzten/Anfang diesen
Jahres als ich mal einen gesucht hatte).

Unten mal ein Beispiel für ADODB/ADONET mit Schema.ini und leicht
skurilen Testdaten. Dort ist das Datumsformat bewusst in englisch,
da hier doch meist deutsch Standard und ich die Standards überschreiben
wollte.

Der VB.NET Code ist zwar nicht dolle, da er aus einem VB-Beispiel
stammt und gerade schnell auf VB.NET portiert wurde.
Aber zum Experimentieren sollte es reichen.

Gruss
Elmar
--
Zunächst die SCHEMA.INI:
///
[CSVTest.txt]
ColNameHeader=True
Format=Delimited(;)
CharacterSet=1252
DateTimeFormat=mm\/dd\/yyyy hh\:nn\:ss
DecimalSymbol=,
NumberDigits=2
TextDelimeter="
CurrencySymbol=€
CurrencyDecimalSymbol=,
CurrencyThousandSymbol=.
CurrencyPosFormat=3
CurrencyNegFormat=8
\\\

Die CSVTest.TXT als Input
///
"ID";"TextSpalte";"DatumSpalte";"DoubleSpalte";"CurrencySpalte"
1;"ABC";01/01/2005;1,23;1,23 €
2;"ABC""DEF";12/30/2005;4711,12;4.711,12 €
3;"äöüÄöü;.,""";12/30/1899 14:30:45;-4711,67;-4.711,67 €
\\\


///
Private Sub ReadCSVTextADONet()
' Beispiel zum Lesen einer Text-Datenbank via JET Text-ISAM
Dim jetConnection As ADODB.Connection
Dim textRecordset As ADODB.Recordset
Dim field As ADODB.Field

jetConnection = New ADODB.Connection
With jetConnection
.Provider = "Microsoft.Jet.OLEDB.4.0"
' Weiteres i. a. in der SCHEMA.INI des Verzeichnisses
' siehe auch Online Hilfe zu Text-Treiber
.Properties("Extended Properties").Value = "Text;"
' Erwartet hier ein Verzeichnis
.Properties("Data Source").Value = "F:\Eigene Dateien"
.Open()
End With

textRecordset = New ADODB.Recordset
' Name der Datei = Tabelle
textRecordset.Open("CSVTest.txt", jetConnection, _
ADODB.CursorTypeEnum.adOpenForwardOnly, _
ADODB.LockTypeEnum.adLockReadOnly, _
ADODB.CommandTypeEnum.adCmdTable)
For Each field In textRecordset.Fields
Console.Write("{0}{1}", field.Name, vbTab)
Next field
Console.WriteLine()

Do While Not textRecordset.EOF
For Each field In textRecordset.Fields
Console.Write("{0}{1}", field.Value, vbTab)
Next field
Console.WriteLine()
textRecordset.MoveNext()
Loop

textRecordset.Close()
jetConnection.Close()
End Sub
\\\

///
Private Sub ReadCSVTextNet()
' Beispiel zum Lesen via Jet DataAdapter
Dim jetConnection As OleDb.OleDbConnection
Dim textCommand As OleDb.OleDbCommand
Dim dataReader As OleDb.OleDbDataReader

jetConnection = New OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Extended Properties='Text;';" & _
"Data Source='F:\Eigene Dateien';")
jetConnection.Open()

textCommand = New OleDbCommand("CSVTest.txt", jetConnection)
textCommand.CommandType = CommandType.TableDirect

dataReader = textCommand.ExecuteReader

If dataReader.HasRows Then
For fieldIndex As Integer = 0 To dataReader.FieldCount - 1
Console.Write("{0}{1}", dataReader.GetName(fieldIndex), vbTab)
Next fieldIndex
Console.WriteLine()
End If

Do While dataReader.Read()
For fieldIndex As Integer = 0 To dataReader.FieldCount - 1
Console.Write("{0}{1}", dataReader.GetValue(fieldIndex), vbTab)
Next fieldIndex
Console.WriteLine()
Loop

dataReader.Close()
jetConnection.Close()
End Sub
\\\
Loading...