Autor |
Beitrag |
glants
      
Beiträge: 20
|
Verfasst: Fr 28.08.09 23:15
Hallo Leute !
Ich habe in C# einige Abfragen an Access gemacht, an der unten stehenden beiße ich mir allerdings die Zähne aus. Ich bekomme einfach nichts in das DataGrid. Wenn ich beim Debuggen das SQL-Statement kopiere und direkt in Access verwende bekommen ich die gewünschten Datensätze. Wo liegt mein Problem ?
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: 27:
| string connectionstring = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Daten\Gernot\Studium\3.Semester\C#\C#_Projekt\Telefonie.mdb;User Id=admin;Password=;"; tb2 = tb2.Insert(0, "\"*"); tb2 = tb2.Insert(tb2.Length, "*\"");
StringBuilder SqlRuf = new StringBuilder(); SqlRuf = SqlRuf.Append("SELECT Rufnummer, Ziel, [Zone], Datum, Verbindungszeit, Anfang, Dauer, Betrag "); SqlRuf = SqlRuf.Append("FROM tblTelekom "); SqlRuf = SqlRuf.Append("WHERE (((Rufnummer) LIKE "); SqlRuf = SqlRuf.Append(tb2); SqlRuf = SqlRuf.Append(") AND ((Datum) Between "); SqlRuf = SqlRuf.Append(sd1); SqlRuf = SqlRuf.Append(" AND "); SqlRuf = SqlRuf.Append(sd2); SqlRuf = SqlRuf.Append(")) "); DataSet myDS = new DataSet(); using (OleDbConnection conn = new OleDbConnection(connectionstring)) { OleDbDataAdapter adapter = new OleDbDataAdapter(); adapter.SelectCommand = new OleDbCommand(SqlRuf.ToString(), conn); OleDbCommandBuilder builder = new OleDbCommandBuilder(adapter); adapter.Fill(myDS, "tblTelekom");
dataGridView1.DataSource = myDS; dataGridView1.DataMember = "tblTelekom"; } |
Das sich daraus ergebende SQL-Statemeent:
SQL-Anweisung 1: 2: 3:
| SELECT Rufnummer, Ziel, [Zone], Datum, Verbindungszeit, Anfang, Dauer, Betrag FROM tblTelekom WHERE (((Rufnummer) LIKE "*4711*") AND ((Datum) Between |
Kann mir jemand einen Tipp geben ?
Ddanke im voraus und mfg
Glants
|
|
JüTho
      
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
|
Verfasst: Sa 29.08.09 09:43
Jetzt sind wir an der Stelle, vor der ich dich bereits gewarnt hatte:
Zitat: | Benutze für variable Inhalte eines SQL-Befehls niemals String-Verknüpfung, sondern immer DbParameter! |
Siehe [Artikelserie] Parameter von SQL Befehlen. Der korrekte Weg vermeidet solche Probleme von vornherein:
SQL-Anweisung 1: 2: 3:
| SELECT Rufnummer, Ziel, [Zone], Datum, Verbindungszeit, Anfang, Dauer, Betrag FROM tblTelekom WHERE (Rufnummer LIKE ?) AND (Datum Between ? AND ?); |
Für meinen Geschmack gibt es auch zu viele runde Klammern; die sollten eigentlich nicht stören, aber um Spaltennamen herum kommt der OledbProvider vielleicht durcheinander.
Gruß Jürgen
PS. Dein Code sieht von der Syntax her korrekt aus. Es gibt aber, wie ich in den Parameter-Artikeln erläuterte, gerade bei Access sehr viele unerklärliche Probleme, die mit Parametern gar nicht auftreten.
|
|
glants 
      
Beiträge: 20
|
Verfasst: So 30.08.09 10:59
Hallo Jürgen !
Danke für den Hinweis. Habe verstanden warum das nicht über Strings gelöst werden soll. Ich habe mich auch durch deine angegebenen Links "gekämpft". Ganz klar ist mir das aber nicht. Scheinbar gibt es Unterschiede zw. SQL-DBs und Access-DBs. Wie geht's weiter ? Ich bekomme bei meinen "Versuchen" die Fehlermeldungen - "Der Typ- oder Namespacename "OleDBCommand" konnte nicht gefunden werden" und "Die beste Übereinstimmung für die überladene system.Data.OleDb.OleDbCommand.OleDbCommand(string, System.Data.OleDb.OleDbConnection)-Methode hat einige ungültige Argumente." Ich weiß echt nicht mehr weiter - und bin am überlegen ob ich, aus Zeitgründen die Abfragen (Strings) die ich habe lasse und die besprochen einfach "spritze".
mfg
Glants
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17:
| string connectionstring = @"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Daten\Gernot\Studium\3.Semester\C#\C#_Projekt\Telefonie.mdb;User Id=admin;Password=;"; using (SqlConnection connection = new SqlConnection(connectionstring)) { connection.Open();
StringBuilder sb = new StringBuilder(); sb.AppendLine("SELECT [Rufnummer], [Ziel], [Zone], [Datum], [Verbindungszeit], [Anfang], [Dauer], [Betrag] "); sb.AppendLine("FROM [tblTelekom] "); sb.AppendLine("WHERE (Rufnummer LIKE ?) AND (Datum Between ? AND ?)");
using (OleDBCommand cmd = new OleDbCommand(sb.ToString(), connection)) { cmd.Parameters.AddWithValue("Rufnummer", tb2); cmd.Parameters.AddWithValue("Datum", d1); cmd.Parameters.AddWithValue("Datum", d2); } } |
|
|
Kha
      
Beiträge: 3803
Erhaltene Danke: 176
Arch Linux
Python, C, C++ (vim)
|
Verfasst: So 30.08.09 13:18
Für OLE brauchst du auch eine OleDbConnection - wie du es am Anfang schon hattest. Und was an "OleDBCommand" falsch ist, sollte dir bei näherem Hinsehen selbst auffallen  .
PS: Einen Stringbuilder brauchst du jetzt ja eigentlich nicht mehr, ich würde Multi-Line Strings verwenden:
C#-Quelltext 1: 2: 3:
| var query = @" SELECT ... FROM ..."; |
_________________ >λ=
|
|
glants 
      
Beiträge: 20
|
Verfasst: So 30.08.09 13:29
Danke für die Antwort !
Habe noch etwas herum gebaut und bin auf folgenden Code gekommen:
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: 27: 28: 29: 30: 31: 32:
| string conStrg = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=" + Application.StartupPath + "\\Telefonie.mdb";
OleDbConnection conn = new OleDbConnection(); conn.ConnectionString = conStrg;
string sqlStrg = "SELECT * FROM tblTelekom WHERE Rufnummer Like ? And Datum BETWEEN ? AND ? ORDER BY Datum";
OleDbCommand cmd = new OleDbCommand(); cmd.CommandText = sqlStrg; cmd.Connection = conn; cmd.Parameters.Add("@Rufnummer", OleDbType.VarChar).Value = textBox2.Text; cmd.Parameters.Add("@DateAndTime", OleDbType.DBDate).Value = dateTimePicker1.Value; cmd.Parameters.Add("@DateAndTime", OleDbType.DBDate).Value = dateTimePicker2.Value; OleDbDataAdapter da = new OleDbDataAdapter(cmd); DataSet ds = new DataSet(); try { conn.Open(); da.Fill(ds, "tblTelekom"); } catch (Exception ex) { MessageBox.Show(ex.ToString()); } dataGridView1.DataSource = ds; dataGridView1.DataMember = "tblTelekom"; |
Die Access DB wird auch abgefragt und das DataGrid gefüllt, jedoch nur wenn die zeile cmd.Parameters.Add("@Rufnummer", OleDbType.VarChar).Value = textBox2.Text; nicht drin ist. Sonst wird nichts angezeigt. Was übersehe ich da bloß ?
mfg
Glants
|
|
JüTho
      
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
|
Verfasst: So 30.08.09 17:17
Hallo,
such einmal in der "Artikelserie" einen Hinweis, wie bei LIKE zu verfahren ist.
Benutze bitte auch für die DateTime-Parameter unterschiedliche Namen; sonst kommt es ggf. zum nächsten Fehler (das ist nicht sicher, aber sehr gut möglich).
Gibt es einen Grund, warum du in dieser Methode ein neues DataSet erzeugst, statt ein vorhandenes erneut zu benutzen?
Gruß Jürgen
|
|
glants 
      
Beiträge: 20
|
Verfasst: So 30.08.09 22:14
Danke !
Den Hinweis mit "Like" habe ich einfach überlesen, gleich geändert - und siehe - "kaum macht mann's richtig läuft's schon"
C#-Quelltext 1:
| cmd.Parameters.AddWithValue("@Rufnummer", "%" + tb2 + "%"); |
Nein, es gibt keinen Grund warum ein neues DS erzeugt wird, aber blöde frage - wo soll das vorhandene sein ?
mfg
Glants
|
|
JüTho
      
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
|
Verfasst: Mo 31.08.09 10:35
glants hat folgendes geschrieben : | Nein, es gibt keinen Grund warum ein neues DS erzeugt wird, aber blöde frage - wo soll das vorhandene sein ? |
Naja, das DataSet wird doch sowieso zur Anzeige von Daten benötigt. Also wird es "in der Regel" bereits vom Designer erstellt und in das Formular eingebunden. (Es gibt viele Wege, deswegen kann ich nicht genau sagen, wann und wo das geschieht.) Dieses DataSet sollte dem Fill-Befehl zur Verfügung gestellt werden.
Wenn du es nirgends findest, dann mach es manuell: Im Formular wird ein DataSet als Bestandteil deklariert; in FormLoad wird es erzeugt (es genügt der Aufruf eines Konstruktors); an die Methode, die das Einlesen erledigt, wird es als ref-Parameter übergeben.
Gruß Jürgen
|
|
glants 
      
Beiträge: 20
|
Verfasst: Mo 31.08.09 15:19
Danke für die Aufklärung - ich seh' schon, da gibt es noch einiges zu lernen !
mfg
Glants
|
|
|