VB Daten auslesen...

AThlord

Lt. Junior Grade
Registriert
Sep. 2005
Beiträge
271
Hallo

Ich habe ein ziemlich einfaches problem, bekomme e aber nicht gelöst.
bin ziemlicher anfänger auf dem gebiet programmieren.

also:

ich habe ein programm was daten die "datenbank.mdb" speichert.

nun will ich das man auch andere datenbanken angeben kann. ich habe eine sub geschrieben die den pfad der augewählten datei in die "path_database.mdb " speichert. das funktioniert auch.


nun will ich, dass jedesmal wenn der anwender daten in "datenbank.mdb" speichern will, der pfad aus "path_database.mdb " geladen wird... aber das bekomme ich nicht hin...

es soll so funktionieren dass, das was aus "path_database.mdb " ausliest in dem string db2 gespeichert wird. diesen gebe ich dann als quelle für die "datenbank.mdb" an.

hier das was ich jetzt hatte aber nicht geht:

Try


db2="Provider=Microsoft.Jet.OLEDB.4.0;DataSource=C:\DokumenteundEinstellungen\Computer1\EigeneDateien\VisualStudio2005\Projects\sits-nebka\sits-nebka\path_database.mdb"

Dim conn2 As New Data.OleDb.OleDbConnection(db2)

Dimcmd2AsNewData.OleDb.OleDbCommand("Select*from
datenbank_pfad",conn2)

Dim sreader As OleDb.OleDbDataReader



conn2.Open()

sreader = cmd2.ExecuteReader()

db = sreader.GetString(1)





Catch ex As Exception
MessageBox.Show("Fehler beim Auslesen der Pfad-Datenbank!", "Fehler", MessageBoxButtons.OK, MessageBoxIcon.Error)
Exit Sub

End Try





wäre euch dankbar wenn ihr ne idee habt. ich muss oledb benutzen.
und bitte ausfürlich erklären.... :)

gruß athlord
 
hallo??? das weiß niemand ???
 
1.) Ich verstehe die Aufgabenstellung nicht ganz. Du hast eine Datenbank, wo der Pfad zu deiner Ziel-Datenbank steht? Das würde ich einmal als sehr umständlich bezeichnen. Ein einfaches Config File wäre da denke ich einmal besser. Ich habe immer eine config.ini mit dem Format Name=Value. Solange du kein Enter im Value hast, funktioniert das wunderbar. Das vor dem ersten = ist der Name der Option, der Rest der Wert. Wenn du willst, kann ich dir den Code für die Klasse geben.

2.) Wie schreibt der User die Daten in die Datenbank? Über dein Programm, oder über Access selbst.

3.) Normalerweise muss man immer erst mit Read eine Zeile lesen. Es empfiehlt sich, wenn du nicht 1 Mio. Datensätze auf einmal liest, dass du dir eine Funktion GetValue, ExecuteUpdate etc. schreibst. Ich benutze immer System.Data.SqlClient auf einem SQLServer.

Der Aufruf schaut so aus:

dim connectionString as String = 'Dein connection String
dim db as New DB(connectionString) 'Globale Variable, die einmal erzeugt wird und immer verwendet wird

Einen Wert auslesen:
dim einzelne_zahl as Integer = db.getValue("select int1 from table1 where ID=4711")
dim anzahl as Integer = db.getValue("select count(*) from table1")
dim einzelner_string as String = db.getValue("select str1 from table1=0815")

Einen Datensatz auslesen:
dim einzelner_datensatz() as Object = db.getDS("select int1,int2,str1,str2 from table1 where ID=4711")
dim wert1 as Integer=einzelner_datensatz(0)
dim wert2 as Integer=einzelner_datensatz(1)
dim str1 as String=einzelner_datensatz(2)
dim str2 as String=einzelner_datensatz(3)

Mehrere Datensätze auslesen:
dim mehrere_datensaetze as Queue = db.getMultiDS("select int1, int2, str1, str2 from table1")

for i as Integer=0 to mehrere_datensaetze.count-1 '-1 deshalb, weil das letzte Element laenge-1 ist, wenn wir bei 0 zu zählen anfangen

dim current_ds() as Object = mehrere_datensaetze.Dequeue()
dim wert1 as Integer=current_ds(0)
dim wert2 as Integer=current_ds(1)
dim str1 as String=current_ds(2)
dim str2 as String=current_ds(3)
next

Ein Update ohne Rückgabewert schicken:
dim anzahl as Integer = db.executeUpdate("update table1 set int1=5 where int1=3") 'Alle 5er auf 1er setzen
msgbox "Es wurden "+anzahl+" Werte ersetzt"

db.executeUpdate("delete * from table1 where ID=4711") 'Delete ausführen. Rückgabewert, wird zwar geliefert, interessiert uns aber nicht und wird nicht gespeichert.


Hier ist der Code der Klasse (auf das wesentliche reduziert, habe noch ein paar Funktionen z.B. zum Datum umwandeln, ' in Strings ersetzen etc.). Am Besten in ein eigenes File kopieren:

Code:
Imports System.Data.SqlClient

Public Class DB
    Dim connectionString As String
    
    Public Sub New(ByVal connectionString As String)
        Me.connectionString = connectionString
    End Sub

    Public Function getScalar(ByVal statement As String) As Object
        Dim conn As New SqlConnection(connectionString)

        conn.Open()

        Dim command As New SqlCommand(statement, conn)
        Dim ret As Object = command.ExecuteScalar()
        conn.Close()

        Return ret
    End Function

    Public Function getDS(ByVal statement As String) As Object()
        Dim conn As New SqlConnection(connectionString)

        conn.Open()

        Dim command As New SqlCommand(statement, conn)
        Dim reader As SqlDataReader = command.ExecuteReader()

        Dim line(reader.FieldCount - 1) As Object

        If Not reader.HasRows Then
            reader.Close()
            conn.Close()
            Return Nothing
        End If

        reader.Read()
        reader.GetValues(line)

        For i As Integer = 0 To line.Length - 1
            If DBNull.Value.Equals(line(i)) Then
                line(i) = Nothing
            End If
        Next
        
        reader.Close()
        conn.Close()

        Return line
    End Function

    Public Function getMultiDS(ByVal statement As String) As Queue
        Dim ret As New Queue
        Dim conn As New SqlConnection(connectionString)

        conn.Open()

        Dim command As New SqlCommand(statement, conn)
        Dim reader As SqlDataReader = command.ExecuteReader()

        While reader.Read
            Dim line(reader.FieldCount - 1) As Object
            reader.GetValues(line)
            ret.Enqueue(line)
        End While

        reader.Close()
        conn.Close()

        Return ret
    End Function

    Public Function executeUpdate(ByVal statement As String) As Integer
        Dim conn As New SqlConnection(connectionString)

        conn.Open()

        Dim command As New SqlCommand(statement, conn)
        Dim ret As Integer = command.ExecuteNonQuery
        conn.Close()

        Return ret
    End Function
End Class

Anmerkung: Die Funktion getDS ist gedacht, wenn klar ist, dass nur 1DS zurück kommt. Wenn du das auf eine fette Tabelle mit 1Mio. Datensätze ausführst, dann wird eventuell die Performance am Server darunter leiden. Benutze hier besser folgende Syntax:
"select top 1 int1,int2,str1,str2 from table1 order by ID"
Hier bekommst du nur den ersten Datensatz.

Anmerkung: Verwende NIEMALS in deinem Code die Syntax "select * from table1". Gib die Felder, die du haben willst, immer explicit an. Das hat mehrere Gründe:
a) Laut Definition ist die Reihenfolge der Spalten einer Datenbank beliebig, genauso wie die Reihenfolge der Zeilen ohne order by. Es kann also auch gut sein, dass sich die Felder ändern und irgendwann kommt das einmal komplett verkehrt daher und man wundert sich, weil es ja immer funktioniert hat.
b) Es kann gut sein, dass du deine Datenbank einmal änderst. Manche Datenbanken sind über 20-30 Jahre im Einsatz (das war zu Zeit von Pascal, Cobol etc.) und werden manchmal erweitert um ein paar Felder. Da ist es dann toll, wenn in einem alten Bankenprogramm in Cobol so ein Code vorkommt und es das Programm auf einmal aufstellt, weil es dann 2 Werte statt einem bekommt und man sich dann jemanden sucht, der das überhaupt noch warten kann. Sag nicht, dein Programm wird es nie solange geben. Wenn es nur eine Hausübung ist, dann stimmt das zwar wahrscheinlich, aber das weiß von vorher nicht.


Anmerkung: Es ist sehr mutig von dir, wenn du eine allgemeine Exception abfängst und dann die Schuld auf die Datenbank schiebst, gerade während dem Testen. Während dem Testen, gebe ich die Exception einfach so aus, wie sie kommt mit ex.message. Dann sieht man gleich, woran es liegt und nur dort, wo es Sinn macht z.B. wenn der Kunde Mist eingeben kann fange ich eine bestimmte Exception ab (z.B. SQLException, FileNotFoundException etc.) und gebe dann einen schönen Usertext aus. Für den Anwender ist es meistens sowieso irrelevant, was da steht, wenn er keine Verbindung bekommt, aber wenn sich der dann bei dir rührt, dann ist es sehr hilfreich, wenn etwas da steht von "Keine Rechte zum Zugriff auf Tabelle" oder eben "Servernamen kann nicht aufgelöst werden" etc. Das ist gut für die Fehlersuche. Die Exceptions, wo es wirklich schöne Texte gibt, sehen aus wie "Usernamen oder Passwort falsch", "Das Laufwerk, das sie angegeben haben, existiert nicht" oder "Bitte geben Sie bei dem Feld Anzahl eine Zahl an" (wenn der User keine Ziffern eingibt) etc. So wie du es machst, kann es auch gut passieren, dass du z.B. durch 0 dividierst, du keinen RAM mehr hast etc. und als Fehlermeldung kommt dann "kann nicht auf SQL Server zugreifen". Was das für ein Murks ist, sieht man, wenn man in den Windows Editor irgendeinen Scheiß eingibt, was er nicht verträgt und er dann sagt "Nicht genügend RAM verfügbar" weil das einfach an einer Stelle passiert, wo es ihn aufhaut, wenn nicht genug RAM da ist, aber hier das Problem an etwas ganz Anderem liegt.
 
danke dirfür deinen sehr ausführlicehn kommentar!

werde das mal ausproebieren... mal ne frage: kann ich sql einach mi oledb ersetzten? muss nämlich oledb benutzen.... und du hast das ales mit sql aufgeschrieben..

und auch danke für die tipps die den try/catch block betreffen, das wusste ich noch gar nich...


werde dann mal später berichten ob es geklappt hat..
gruß athlord
 
Zurück
Oben