Autor Beitrag
blumione
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Mi 03.12.08 18:23 
Hallo zusammen

Kann mir jemand ein einfaches Beispiel zum Lesen und Schreiben in einer Access Datenbank geben? Ich habe einzelne Hilfen im Internet gefunden, aber leider funktionieren die nicht und ich kann nicht nachfragen.

Lesen habe ich so gelernt:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
            listBox1.Items.Clear();

            // Verbindungszeichenfolge: 
            const string conStr = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=Nordwind.mdb";
            const string selStr = "SELECT * FROM Kunden WHERE Ort = 'London'";  // SQL-Abfrage

            OleDbConnection conn = new OleDbConnection(conStr);
            OleDbCommand cmd = new OleDbCommand(selStr, conn);
            OleDbDataReader dr;
            conn.Open();
            dr = cmd.ExecuteReader();

            while (dr.Read())
            {
                string str = "";
                //                str += dr[i] + " - ";
                str += dr["Kunden-Code"] + " - ";
                str += dr["Firma"] + " - ";
                str += dr["Kontaktperson"] + " - ";
                str += dr["Strasse"] + " - ";
                str += dr["PLZ"] + " - ";
                str += dr["Ort"] + " - ";
                listBox1.Items.Add(str);
            }
            dr.Close();
            conn.Close();


Fürs schreiben habe ich die SELECT Funktion mit der INSERT Funktion anpassen wollen. Leider funktioniert das nicht :(

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
            const string connectionstring = "provider=Microsoft.JET.OLEDB.4.0; Data Source = Nordwind.mdb";
            const string SQL = "INSERT INTO Kunden VALUES('BLUMI', 'Peter Hans Firma', 'Peter Meier', 'Inhaber', 'Olololstrasse 17')";

            OleDbConnection conn = new OleDbConnection(connectionstring);
            OleDbCommand cmd = new OleDbCommand(SQL, conn);

            conn.Open();

            //OleDbCommand cmd = con.CreateCommand();
            cmd.CommandText = SQL;
            cmd.CommandType = CommandType.Text;
            cmd.ExecuteNonQuery();

            cmd.Dispose();

            conn.Close();


Lg blumione

Edit: cs-Codes wurden nicht korrekt umgewandelt.. :?
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mi 03.12.08 18:44 
user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Fürs schreiben habe ich die SELECT Funktion mit der INSERT Funktion anpassen wollen. Leider funktioniert das nicht :(

Das ist keine richtige Problembeschreibung: Fehler vom Compiler? Fehler zur Laufzeit? Welche Fehler? Wird nicht gespeichert, oder wird falsch gespeichert, oder sind die Änderungen beim Neustart des Programms wieder weg?

Vorläufig einige grundsätzliche Hinweise:

Wer bei VisualStudio nicht aufpasst (Eigenschaften der Datei), erzeugt mit Access oder MS-SQL Server bei jedem Programmstart eine neue Version der Datenbank-Datei.

Eine Einführung in ADO.NET ist zu finden bei OpenBook Visual C# Kap.25 ff. Die Sql-Klassen sind durch OleDb-Klassen zu ersetzen; die Parameter in SQL-Befehlen werden nur durch '?' ohne Namen gekennzeichnet.

Setze DbConnection und DbCommand in einen using-Block, das vereinfacht den Code, kapselt ihn besser und regelt Close und Dispose automatisch:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
using(OleDbConnection conn = new OleDbConnection(connectionstring))
{
    using(OleDbCommand cmd = new OleDbCommand(SQL, conn)) {

            conn.Open();

            cmd.CommandText = SQL;
            cmd.CommandType = CommandType.Text;
            cmd.ExecuteNonQuery();

    }
}

Jürgen
blumione Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Mi 03.12.08 19:10 
Hi JüTho

Vielen Dank für deine Antwort!

Also es hat soeben geklappt mit dem eintragen .)

Geht das mit de verkürzten Schreibweise von dir auch zum auslesen?

Hab in der online Hilfe nur gelesen wie man verbinden kann.. Also die die du mir geschickt hast!

Lg
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Mi 03.12.08 20:08 
user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Also es hat soeben geklappt mit dem eintragen .)

Und woran lag's?

user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Geht das mit de verkürzten Schreibweise von dir auch zum auslesen?

Selbstverständlich. Prüfe und vergleiche mein Code-Beispiel: Was muss daran geändert werden, um es für einen SELECT-Befehl zu benutzen? Fast nichts, nur die Übergabe der Ergebnismenge an das "Äußere" des Programms, z.B. die Listbox.Items.

Noch ein paar Anmerkungen:
  • Diese Art, einen String zusammenzubauen mit "str+=", ist nur bei kurzen und wenigen Strings (bis max. ein paar Hundert) akzeptabel. Sonst ist StringBuilder vorzuziehen.
  • Das Ergebnis eines SELECT-Befehls passt meistens besser in eine DataTable. Dazu benutzt man besser DbDataAdapter.Fill statt DbCommand.ExecuteReader.
  • Vorsorglich weise ich darauf hin, dass ein CommandText möglichst nicht durch eine lange String-Verknüpfung erzeugt werden sollte, sondern mit DbCommand.Parameters. (Bei Dir ist es offensichtlich nur ein Beispiel.)


Gruß Jürgen
blumione Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 22



BeitragVerfasst: Do 04.12.08 00:25 
dann möchte ich es gerne gerade "richtig" lernen :)

es war übringes ein SQL Fehler.. Syntax..

Dein 1. Vorschlag/Tipp mit Stringbuilder habe ich jetzt so umgebaut:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
                        StringBuilder sb = new StringBuilder();
                        sb.Append(dr["Kunden-Code"] + " - ");
                        sb.Append(dr["Firma"] + " - ");
                        sb.Append(dr["Kontaktperson"] + " - ");
                        sb.Append(dr["Strasse"] + " - ");
                        sb.Append(dr["PLZ"] + " - ");
                        sb.Append(dr["Ort"] + " - ");
                        listBox1.Items.Add(sb.ToString());


Wie benutze ich dann Datadapter.Fill korrekt? Ich dachte das wäre für eine einzelne Ausgabe geeignet und OleDBDataReader eben für mehr.. While Schleifen..

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
 

                    OleDbDataReader dr;

                    dr = cmd.ExecuteReader();

                    while (dr.Read())
                    {


das ist ja dann so etwa:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
 
        private DataSet ds;

            ds = new DataSet(); // leeres DataSet erzeugen 
               OleDbDataAdapter da = new OleDbDataAdapter(selStr, conn); // DataAdapter erzeugen 
               da.Fill(ds, "Füllen"); // DataSet füllen (den Namen der Tabelle bestimmen Sie!) 



            DataTable dt = ds.Tables["Füllen"];
            foreach (DataRow custRow in dt.Rows)
            {
                listBox1.Items.Add(custRow["Username"]);
            }


Was ist bei diesen beiden der Unterschied?
Bzw. Wiso ist das DataSet besser, weil ich es nacher immer noch abfragen kann?

Wenn ich den Command Text jetzt doch nicht durch StringBuilder aufbauen soll, sondern durch DbCommand.Parameters.. Wie sieht das dann am Besten aus?

Lg
JüTho
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 2021
Erhaltene Danke: 6

Win XP Prof
C# 2.0 (#D für NET 2.0, dazu Firebird); früher Delphi 5 und Delphi 2005 Pro
BeitragVerfasst: Do 04.12.08 11:13 
user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Wie benutze ich dann Datadapter.Fill korrekt? Ich dachte das wäre für eine einzelne Ausgabe geeignet und OleDBDataReader eben für mehr.. While Schleifen..

Das ist keine korrekte Erklärung. DataSet bzw. DataTable ist sinnvoll, wenn mehr Daten oder Zeilen oder Werte benötigt werden, später erneut benutzt werden und nach Änderungen wieder abgespeichert werden sollen. Eine Standardanwendung geht über ein DataGridView.

Dein Übertrag in eine ListBox ist ein Grenzfall; da ist beides wenig sinnvoll (also egal). :mrgreen: Hinzu kommt manchmal, dass der DbDataAdapter länger dauert; aber das ist sowieso relativ (also in der Praxis meistens irrelevant).

user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
... das ist ja dann so etwa: ...

Was ist bei diesen beiden der Unterschied?

In der Tat so gut wie kein Unterschied.

user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Bzw. Wiso ist das DataSet besser, weil ich es nacher immer noch abfragen kann?

Genau. Der DbDataReader bietet nur ein einmaliges Lesen und zwar nur vorwärts; die DataTable bleibt bei richtiger Anwendung erhalten und kann auch durch BindingSource oder direkten Datenzugriff zum Blättern benutzt werden. (Richtige Anwendung bedeutet: keine Erzeugung mit new nur innerhalb des Einlesens, sondern Deklaration und Erzeugung außerhalb dieser Methode.)

user profile iconblumione hat folgendes geschrieben Zum zitierten Posting springen:
Wenn ich den CommandText jetzt doch nicht durch StringBuilder aufbauen soll, sondern durch DbCommand.Parameters.. Wie sieht das dann am Besten aus?

StringBuilder ist für einen CommandText nicht unbedingt erforderlich, weil das ein relativ kurzer String ist; da ist auch die String-Addition akzeptabel. Aber die variablen Bestandteile sollen möglichst nicht direkt im String enthalten sein. Falsch (als Beispiel mit verschiedenen Datentypen, die so mit Sicherheit nicht funktionieren, sondern zu Exceptions führen):
ausblenden C#-Quelltext
1:
2:
3:
4:
string insertText = "INSERT INTO Kunden VALUES(" + myID.ToString() + ", '"
   + textboxName.Text + "', '"                       //  Name
   + datetimeBirthday.ToShortDateString() + "', "    //  Geburtstag
   + numeric.Value.ToString());";                    //  Rechnungsbetrag

Richtig ist dies (bei MS-SQL o.a. DBMS sehen die Parameter etwas anders aus):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
string insertText = "INSERT INTO Kunden (ID, Name, Birthday, BillValue) 
   VALUES(?, ?, ?, ?);"
;
OledbCommand cmd = new OledbCommand(insertText, conn);
cmd.Parameters.AddWithValue("@ID", myId);
cmd.Parameters.AddWithValue("@Name", textboxName.Text);
cmd.Parameters.AddWithValue("@Birthday", datetimeBirthday);
cmd.Parameters.AddWithValue("@BillValue", numeric.Value);

Der DbProvider setzt die Gänsefüßchen selbständig und nimmt auch die Formatierung korrekt vor.

Jürgen