aus Access Datenbank Spaltenüberschriften auslesen

  • VB.NET

Es gibt 26 Antworten in diesem Thema. Der letzte Beitrag () ist von RodBelaFarin.

    aus Access Datenbank Spaltenüberschriften auslesen

    Hallo,

    weiß jemand, wie ich aus VB2008 Express die Spaltenüberschriften einer Access-Datenbank auslesen kann ?
    Ich möchte meine Insert, Update, Delete Befehle gerne automatisch erstellen lassen, falls sich mal eine Spalte ändert oder hinzukommt.

    Gruß
    Herr Frie
    Mit der folgenden Funktion wird eine Tabelle ersteltt, die alle Eigenschaften einer Tabelle einer DB ausleist.

    VB.NET-Quellcode

    1. Public Function TabellenStruktur(ByVal Tabellenname As String) As DataTable
    2. conn.Open()
    3. Dim DT As DataTable = conn.GetSchema("Tables")
    4. Dim SqlCmd As SqlCommand = conn.CreateCommand()
    5. Dim sqldr As SqlDataReader
    6. With SqlCmd
    7. .CommandText = "Select * From " & Tabellenname
    8. .CommandType = CommandType.Text
    9. sqldr = .ExecuteReader
    10. End With
    11. DT = sqldr.GetSchemaTable
    12. conn.Close()
    13. Return DT
    14. End Function
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Das ist ja ne geile Sache !

    Hab ich mir direkt mal so abgespeichert um Datenbanken/-typen zu analysieren. Ich mußte nur das sql gegen Oledb austauschen.
    Das ist jetzt aber nicht direkt das was ich suche.

    Ich möchte nur alle Header Texte, am Besten in ein Array einlesen.
    Dadurch kann ich dann mit einer Schleife meine Insert, etc. Befehle automatisch erstellen lassen.

    Edit : Ok, hab mir die Überschriften einfach aus dem Dt rausgeholt, jetzt hab ich es.

    Gruß
    Herr Frie

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „HerrFrie“ ()

    Hallo, ich muss diesen alten Thread nochmal ausgraben, denn das ist genau das, was ich auch suche.
    Habe es wie Herr Frie gemacht und SQL durch OleDB ersetzt. Damit kennt VB bei mir auch alle Deklarationen außer

    VB.NET-Quellcode

    1. Dim DT As DataTable = conn.GetSchema("Tables")


    was brauche ich um das so einbinden zu können oder wie kann ich das abändern?

    Edit: Um's genauer zu sagen: DataTable kennt er nicht.

    MfG

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodBelaFarin“ ()

    Moin,

    das ist schon komisch. Ich habe gerade noch einmal den Code in ein neues Projekt eingefügt und da meckert er kein Datatable an.
    Hast du mal den kompletten Code da ?

    Edit :

    VB.NET-Quellcode

    1. Imports System.Data.OleDb
    2. Public Class Form1
    3. Public Function TabellenStruktur(ByVal Tabellenname As String) As DataTable
    4. Dim conn As New OleDbConnection
    5. conn.Open()
    6. Dim DT As DataTable = conn.GetSchema("Tables")
    7. Dim SqlCmd As OleDbCommand = conn.CreateCommand()
    8. Dim sqldr As OleDbDataReader
    9. With SqlCmd
    10. .CommandText = "Select * From " & Tabellenname
    11. .CommandType = CommandType.Text
    12. sqldr = .ExecuteReader
    13. End With
    14. DT = sqldr.GetSchemaTable
    15. conn.Close()
    16. Return DT
    17. End Function
    18. End Class


    So habe ich keine Fehleranzeige bei mir. In dem Original Schnippsel ist die Deklaration von conn nicht drinn gewesen, die wurde da evtl. global irgendwo anders deklariert oder nur einfach vergessen.

    Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „HerrFrie“ ()

    Hallo, habe in dem Moment deines Posts ne Lösung gefunden. Ich muss es als System.Data.DataTable deklarieren.
    Allerdings habe ich so das Gefühl als würde er die Eigenschaften der Tabelle nicht richtig auslesen. Sie stimmten jedenfalls nicht mit meiner Testtabelle überein. Hier mal der gesamte Code

    VB.NET-Quellcode

    1. Dim DBVerbindung As New OleDbConnection
    2. Dim cmd As New OleDbCommand
    3. Dim reader As OleDbDataReader
    4. Dim DBPfad As String
    5. DBPfad = PathDB 'Verzeichnis der DB
    6. DBVerbindung.ConnectionString = _
    7. "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    8. "Data Source=" & DBPfad
    9. Try
    10. cmd.Connection = DBVerbindung
    11. cmd.CommandText = "SELECT * FROM Testtabelle"
    12. DBVerbindung.Open()
    13. Dim LokalTabelle As System.Data.DataTable = DBVerbindung.GetSchema("Tables")
    14. reader = cmd.ExecuteReader()
    15. reader.Read()
    16. LokalTabelle = reader.GetSchemaTable
    17. DBVerbindung.Close()
    18. Catch ex As Exception
    19. LokalDBVerbindung.Close()
    20. MsgBox(ex.Message)
    21. End Try


    ich frag mal so um weiter zu kommen:

    Edit: Ok hab mir die Überschriften einfach aus dem Dt rasugeholt, jetzt hab ich es.
    Wo genau stehen die in dem DT drin? Und stehen da dann sogar alle Zellen aus der Tabelle irgendwo dadrin?

    Dieser Beitrag wurde bereits 3 mal editiert, zuletzt von „RodBelaFarin“ ()

    VB.NET-Quellcode

    1. DBPfad = PathDB 'Verzeichnis der DB
    2. DBVerbindung.ConnectionString = _
    3. "Provider=Microsoft.Jet.OLEDB.4.0;" & _
    4. "Data Source=" & LokalDBPfad
    DBPfad oder LokalDBPfad
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    visuell brauch ich das gar nicht.

    ich kann mir die eigenschaften inkl. werte ja im debugger anzeigen lassen.

    vielleicht sollte ich nochmal genau beschreiben, was ich eigentlich vorhabe:

    ich habe 2 datenbanken mit verschiedenen tabellen, nennen wir sie lokalDB und serverDB.

    nun will ich daten aus tabelle A von der lokalDB in die tabelle A der serverDB schreiben.
    die tabellen sind sehr ähnlich, aber auf der serverDB gibt es noch ein paar zusätzliche felder in der tabelle A, die es auf der lokalDB nicht gibt.
    ebenso gibt es eine tabelle B, C, D...

    ich will von der lokalDB also alle datensätze aus tabelle A, B, C, D auswählen und in die entsprechende tabelle der serverDB kopieren.

    deshalb mein vorgehen: zuerst mal rausfinden wieviele zeilen und spalten z.b. tabelle A hat. dann bei jeder zelle prüfen ob auf der serverDB diese spalte auch vorhanden ist. wenn ja, dann die zelle beschreiben, wenn nicht, zur nächsten zelle gehen und gucken ob das die entsprechende spalte ist.
    ok, nochmal neu. das war vllt etwas viel auf einmal.

    ich versuchs nochmal geordnet.

    ich habe 2 datenbanken mit etwa ähnlich tabellen. beispiel:

    Quellcode

    1. Tabelle A von DB1
    2. Spalte A Spalte C Spalte E
    3. a aa aaa
    4. b bb bbb


    Die sollen jetzt nach DB2 dort in die Tabelle A übertrageb werden

    Quellcode

    1. Tabelle A von DB2
    2. Spalte A Spalte E Spalte D Spalte B Spalte C


    Nun sollen alle Daten aus Tabelle A von DB1 nach Tabelle A in DB2 kopiert werden, sodass diese danach so aussieht:

    Quellcode

    1. Tabelle A von DB2
    2. Spalte A Spalte E Spalte D Spalte B Spalte C
    3. a aaa aa
    4. b bbb bb
    Ich glaube du hast diesen Thread nicht so ganz verstanden.
    Das, worum es hier ging war, wir man die FelderTypen einer Datenbank ausliest.

    Soll heißen, der Code überprüft in einer bestimmten Tabelle die Felder/Spalten und zeigt dir an, was das für Felder sind.
    Beispiel:

    Tabelle 1
    ID | Anrede | Name

    Angezeigt wird dann sowas wie im Bild.
    Das hat aber nichts damit zu tun, was du scheinbar vorhast, sorry.

    Gruß
    HerrFrie
    Bilder
    • Schema.JPG

      31,73 kB, 948×142, 301 mal angesehen
    nur indirekt.

    ich wollte die spalte ColumnName aus deinem Anhang zwischen beiden Tabellen vergleichen und wenn die übereinstimmen, soll er die entsprechenden Daten reinschreiben.

    Vielleicht denke ich auch viel zu umständlich, aber mir fällt keine andere Lösung ein.
    dann versuch ich's nochmal anders:

    die DataTable LokalTabelle wird jetzt belegt, aber ich kann z.b. nicht auf die Eigenschaft LokalTabelle.ColumnName zugreifen. Kennt VB nicht.
    Und LokaleTabelle.Columns.Count zeigt mir immer einen falschen Wert an.

    LokaleTabelle.Rows.Count gibt hingegen richtigerweise 24 aus.

    RodBelaFarin schrieb:

    nur indirekt.

    ich wollte die spalte ColumnName aus deinem Anhang zwischen beiden Tabellen vergleichen und wenn die übereinstimmen, soll er die entsprechenden Daten reinschreiben.

    Vielleicht denke ich auch viel zu umständlich, aber mir fällt keine andere Lösung ein.


    Die einfachste Lösung wäre: Nimm dafür einfach eine ODCB-Connection, öffne auf die Tables jeweils ein eigenes ADODB.Recordset und über recordset.fields(index).Name hast Du dann problemlos den Column-Name (der ja logischerweise den Field-Name darstellt wenn Du nicht mit AS den Fieldname verändert hast), sieht in etwa so aus (Syntax-Fehler vorbehalten da ich das nur schnella aus dem Bauch raus geschrieben habe ^^):

    VB.NET-Quellcode

    1. Dim rst_Ori As New ADODB.RecordSet
    2. Dim rst_Tar As New ADODB.RecordSet
    3. Dim cnn As New ADODB.Connection
    4. Dim i As Integer
    5. cnn.ConnectionString = <Mein Connection-String>
    6. cnn.open
    7. rst_Ori.Open "SELECT * FROM tblMeinOriginal", cnn, ... etc.
    8. rst_Tar.Open "SELECT * FROM tblMeinTarget", cnn, ... etc.
    9. For i = 0 to rst_Ori.Fields.Count - 1
    10. Try
    11. rst_Tar.fields(rst_Ori.Fields(i).Name).Value = rst_Ori.Fields(i).Value
    12. Catch
    13. End Try
    14. Next i
    15. ' ... und dann wieder alles sauber closen


    Das Try Konstruktor ist eine unsaubere Lösung für den Fall das ein Field mit dem entsprechenden Namen nicht im rst_Tar existiert. Dafür solltest Du Dir dann selber was sauberes einfallen lassen. ;)

    Gruß

    Rainer
    Das sieht so als als wäre das genau das, was ich brauche. :)

    Mit Recordsets kenne ich mich überhaupt nicht aus (bin eh noch ziemlich neu in der SQL-Szene ;) ), aber dann werde ich mir das mal genauer anschauen. Damit scheint mein Problem wirklich gut gelöst werden zu können.

    Danke!

    Edit:
    Hat jemand zum Thema Recordset ein gutes Tutorial oder ne Seite, wo dazu mal alles eklärt wird. Finde nämlich nicht wirklich was dazu.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „RodBelaFarin“ ()

    So, habe mich nun einige zeit mit ADODB beschäftigt (Danke raist10 für den Hinweis). Damit scheine ich mein Problem bewerkstelligen zu können, aber es gibtnoch Schwierigkeiten beim umsetzen. ;(

    Wenn ich meinem Recordset eine Tabelle zuweisen will, dann meldet sich VB mit der Fehlermeldung "COMException wurde nicht behandelt. Die Argumente sind vom falschen Typ, liegen außerhalb des Gültigkeitsbereiches oder sind miteinander unvereinbar."

    Hier mal der Code

    VB.NET-Quellcode

    1. Dim ServerDBVerbindung As New ADODB.Connection
    2. Dim DB_RS As New ADODB.Recordset
    3. Dim ServerDBPfad As String
    4. Dim anzdaten As Integer
    5. Dim SQLCode As String
    6. ServerDBPfad = PathDB 'Ermittelt das Verzeichnis Datenbank
    7. ServerDBVerbindung.Provider = "Microsoft.Jet.OLEDB.4.0;"
    8. ServerDBVerbindung.ConnectionString = ServerDBPfad
    9. ServerDBVerbindung.CursorLocation = CursorLocationEnum.adUseClient
    10. ServerDBVerbindung.Mode = ConnectModeEnum.adModeShareDenyNone
    11. SQLCode = "SELECT * FROM Testtabelle"
    12. ServerDBVerbindung.Open()
    13. DB_RS.ActiveConnection = ServerDBVerbindung
    14. DB_RS.CursorType = CursorTypeEnum.adOpenKeyset
    15. DB_RS.LockType = LockTypeEnum.adLockOptimistic
    16. DB_RS.Source = SQLCode
    17. DB_RS.Open()
    18. anzspalten = DB_RS.Fields.Count
    19. DB_RS.Close()
    20. ServerDBVerbindung.Close


    Bei der Zuweisung

    VB.NET-Quellcode

    1. DB_RS.Source = SQLCode


    kommt die Fehlermeldung. Habe nun schon viele verschiedene Ansätze ausprobiert und bei Google gesucht, aber es will nicht funktionieren. Bitte nochmal um Hilfe.

    VB.NET-Quellcode

    1. DB_RS.ActiveConnection = ServerDBVerbindung
    2. DB_RS.CursorType = CursorTypeEnum.adOpenKeyset
    3. DB_RS.LockType = LockTypeEnum.adLockOptimistic
    4. DB_RS.Source = SQLCode
    5. DB_RS.Open()


    Ändere das mal wie folgt ab:

    VB.NET-Quellcode

    1. DB_RS.open SQLCode, ServerDBVerbindung, CursorTypeEnum.adOpenKeyset, LockTypeEnum.adLockOptimistic


    Ist eigentlich die Standard-Syntax um ein ADODB.Recordset zu öffnen.

    Gruß

    Rainer