Laden...

update-query via oledb ausführen

Erstellt von chanderegg vor 15 Jahren Letzter Beitrag vor 15 Jahren 836 Views
C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren
update-query via oledb ausführen

verwendetes Datenbanksystem: Oracle 9i

Hallo zusammen

Ich schreibe ein Programm, welches Daten aus der DB via oledbdatareader ausliest. diese Daten kann ich dann verändern. Wenn ich auf den Speichern-Button drücke sollen die Änderungen in der DB gespeichert werden. Ich erstelle dafür den nötigen query.
Nun möchte ich, dass der query an die DB geschickt und ausgeführt wird. Ich habe im Netz nachgesehen und immer nur die Variante entdeckt, in der man mit einem DataAdapter Parameter hinzufügt.
Ich möchte aber mit meinem oledbcommand Objekt den query zurück geben. Ist dies nicht möglich oder mache ich einen Fehler?

Mein Code sieht so aus (query wurde bereits auf Korrektheit geprüft):


if (SpaltenDatenAnsicht.CurrentRow.Index == SpaltenDatenAnsicht.Rows.Count - 1)
            {
                mySelectQuery = "INSERT INTO xc001 (xcprj,xcver,xctab,xccol,xcord,xcisp,xcish,xcisi,xcdtp,xclen,xcscl,xcdef,xccmt,xcmb1,xcdh1,xccat,xcnuv) VALUES ('" + Projektname + "', '" + Versionnummer + "', '" + Tabellenname + "', '" + SpaltenbezeichnungTextbox.Text + "', '" + OrdinalnummerTextbox.Text + "','" + isPrimary + "', '" + isHistory + "', '" + isSQL + "', '" + hatDatentyp + "', '" + LängeTextbox.Text + "', '" + ScaleTextbox.Text + "', '" + DefaultValueTextbox.Text + "', '" + KommentarTextbox.Text + "', 'User', '" + DateTime.Now + "','" + istKategorie + "', '" + NULLErsatzwertTextbox.Text + ")";
            }
            else
            {
                mySelectQuery =  "UPDATE xc001 SET xcord='" + OrdinalnummerTextbox.Text + "', xcisp='" + isPrimary + "', xcish='" + isHistory + "', xcisi='" + isSQL + "', xcdtp='" + hatDatentyp + "', xccmt='" + KommentarTextbox.Text + "', xccat='" + istKategorie + "', xcnuv='" + NULLErsatzwertTextbox.Text + "', xcmb1='CA', xcdh1='" + DateTime.Now + "' WHERE xcprj='" + Projektname + "' AND xcver='" + Versionnummer + "' AND xctab='" + Tabellenname + "' AND xccol='" + SpaltenbezeichnungTextbox.Text + "'";
            }

            myConnection = new OleDbConnection(sConnectionString);
            myConnection.Open();
            myCommand = new OleDbCommand(mySelectQuery, myConnection);
            bearbeitungErfolgreich = myCommand.ExecuteNonQuery(); //Hier gibt es die Fehlermeldung

            if (bearbeitungErfolgreich == 0)
            {
                MessageBox.Show("funzt");
            }
            else
            {
                MessageBox.Show("ca ne veux pas");
            }

leider gibt es immer die Fehlermeldung: literal does not match format String

365 Beiträge seit 2007
vor 15 Jahren

Hallo chanderegg,

benutze doch in Zukunft Parameter. Hier ein Link OleDbParameter Class
Du kannst in einem Command Objekt auch Parameter einsetzen.

Irgendwo scheinst du eine Diskrepanz zwichen Datentyp der ankommt und Datentyp der erwartet wird zu haben. Ich interpretiere die Fehlermeldung 'doesn't match' so.
Mit Parametern wird dir so eine Fehlermeldung nicht mehr passieren.
Jedenfalls wird Sie dadurch eindeutiger.

Greetz da kubi.

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

Hallo Kubi

Diese Art habe ich schon im Netz entdeckt aber ich bin mir nicht sicher, ob dies für mich das richtige ist. Ich möchte ja die bestehenden Werte überschreiben und nicht neu einfügen.

365 Beiträge seit 2007
vor 15 Jahren

Es ist egal ob Update oder Insert, die Parameter kannst du in beiden Fällen gebrauchen.
Du bekommst im gegenzug eine Art von Typsicherheit und es entfallen die nervigen Hochkommata die dein Statement sehr unübersichtlich machen.


string queryString = "SELECT * FROM Table1 WHERE Field1 LIKE ?";
OleDbCommand command = new OleDbCommand(queryString, connection);
command.Parameters.Add("@p1", OleDbType.Char, 3).Value = "a";

Wie du in dem Beispiel siehst sind die Fragezeichen Platzhalter und im Parameter
sagst du dem Command welcher Datentyp und woher die Value kommt.
So brauchst du bei nachträglichen Änderungen nicht in jedem Statement suchen ob dein Parameter in Hochkommata steht oder nicht.
Ist sehr mühsam bei großen Abfragen.

Versuche doch einfach dein Statement mit Parametern zu erstellen.
Ist am Anfang gewöhnungsbedürftig, jedoch wirst du später gefallen daran finden.
Jede Wette du findest dann den Fehler wesentlich schneller.

Greetz da kubi.

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

Also nochmal für die langsamen:

Ich lese alle Daten aus:


mySelectQuery = "SELECT * FROM xc001 WHERE xcprj = '" + Projektname + "' AND xcver='" + Versionnummer + "' AND xctab = '" + Tabellenname + "' AND xccol = '" + SpaltenDatenAnsicht.CurrentRow.Cells["Spalte"].Value + "'";

Danach stelle ich die Verbindung mit der DB her und lese die Daten aus:


myConnection = new OleDbConnection(sConnectionString);
myConnection.Open();
myCommand = new OleDbCommand(mySelectQuery, myConnection);

Danach möchte ich die Spalte xccmt bearbeiten


myCommand.Parameters.Add("@xccmt", OleDbType.VarChar, 150).Value = KommentarTextbox.Text;

Wenn ich es so mache wird gar nichts gemacht. muss ich mycommand noch den Befehl geben dies auszuführen?

365 Beiträge seit 2007
vor 15 Jahren

Wie sieht dein Select String denn ohne eingefügte Steuerelemente aus?!
Also ohne die + Variable + in dem Select String.

Er sollte ungefähr so aussehen:


"SELECT CustomerID, CompanyName FROM Customers WHERE Country = ? AND City = ?"

Die ? sind Platzhalter für deine Werte.
Dann:


command.Parameters.Add("@Country", OleDbType.VarChar);
command.Parameters["@Country"].Value = TextBoxLand.Text;
command.Parameters.Add("@City", OleDbType.VarChar);
command.Parameters["@City"].Value =TextBoxStadt.Text;

Danach noch dein Command.ExecuteNonQuery() und es sollte funzen?!

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

Wenn ich es ohne die Variabeln mache, habe ich das Problem, dass 140000 Zeilen ausgelesen werden.

Wie kann ich dann sicherstellen, dass es in der richtigen Zeile den Wert eingibt?

Wenn ich es mit meiner Spezifikation auslese, sollte nur eine Zeile ausgegeben werden.
Ich habe nun mein query mit AND xccmt = ? ergänzt und zusätzlich Command.ExecuteNonQuery() im Code eingefügt aber trotzdem wird keine Änderung vorgenommen.

365 Beiträge seit 2007
vor 15 Jahren

Wenn ich es ohne die Variabeln mache, habe ich das Problem, dass 140000 Zeilen ausgelesen werden.

Wie kann ich dann sicherstellen, dass es in der richtigen Zeile den Wert eingibt?

Du machst es doch mit Variablen.
Du kannst doch bei command.Parameters["@xcver"].Value = Versionnummer; eingeben.
Ob TextBox.Text oder irgendeine angelegte Variable ist dem Parameter egal.

Zeig doch mal bitte den Codeausschnitt.

C
chanderegg Themenstarter:in
101 Beiträge seit 2008
vor 15 Jahren

So nun habe ich es endlich gelöst.

Der Fehler war, dass ich das falsche Query genommen habe. Mein Code sieht nun wie folgt aus:


mySelectQuery = "UPDATE xc001 SET xccmt=? WHERE xcprj='" + Projektname + "' AND xcver='" + Versionnummer + "' AND xctab='" + Tabellenname + "' AND xccol='" + SpaltenbezeichnungTextbox.Text + "'";
            myConnection = new OleDbConnection(sConnectionString);
            myConnection.Open();
            myCommand = new OleDbCommand(mySelectQuery, myConnection);

            myCommand.Parameters.Add("@xccmt", OleDbType.VarChar).Value = KommentarTextbox.Text.Trim();
            myCommand.Parameters.Add("@xcord", OleDbType.VarChar).Value = OrdinalnummerTextbox.Text.Trim();
            myCommand.Parameters.Add("@xcisp", OleDbType.Single).Value = isPrimary;
            myCommand.Parameters.Add("@xcish", OleDbType.Single).Value = isHistory;
            myCommand.Parameters.Add("@xcisi", OleDbType.Single).Value = isSQL;
            myCommand.Parameters.Add("@xcdtp", OleDbType.Single).Value = hatDatentyp;
            myCommand.Parameters.Add("@xccat", OleDbType.Single).Value = istKategorie;
            myCommand.Parameters.Add("@xcnuv", OleDbType.VarChar).Value = NULLErsatzwertTextbox.Text.Trim();
            myCommand.Parameters.Add("@xcmb1", OleDbType.VarChar).Value = "CA";
            myCommand.Parameters.Add("@xcdh1", OleDbType.Date).Value = DateTime.Now;

            bearbeitungErfolgreich = myCommand.ExecuteNonQuery();

           
            
            if (bearbeitungErfolgreich == 1)
            {
                MessageBox.Show("funzt");
            }
            else
            {
                MessageBox.Show("wot nid");
            }

@Kubi: Vielen Dank für deine Hilfe

J
3.331 Beiträge seit 2006
vor 15 Jahren

So nun habe ich es endlich gelöst.

Das ist aber doch ziemlich voreilig. Im Befehl steht ein einziges '?' einsam herum, aber Parameters enthält 10 Einträge. Das passt doch hinten und vorne nicht zusammen, und Du wunderst Dich nicht darüber?

kubi hat Dich ganz klar darauf hingewiesen, dass die Parameter das Problem mit den Gänsefüßchen beseitigen. So soll der Befehl aussehen:

mySelectString = "UPDATE xc001 SET xccmt=? WHERE xcprj=? "
  + "AND xcver=? AND xctab=? AND xccol= ?";

Und auch dabei gibt es noch überflüssige Parameter. 8o

Übrigens wundere ich mich über folgende Punkte:

Ein Name bearbeitungErfolgreich klingt nach einer bool-Variablen, aber die Methode gibt einen **int **zurück.

Query heißt auf deutsch Frage. Es ist eher widersinnig, diese Bezeichnung für einen Update-Befehl und ExecuteNonQuery zu benutzen.

Jürgen

PS. Ebenso wie bei NET und C# wären auch in einer Datenbank aussagefähige Tabellen- und Feldnamen äußerst nützlich. xc001 usw. sagen doch überhaupt nichts aus.

365 Beiträge seit 2007
vor 15 Jahren

Hallo juetho,
deine Argumente sind nicht von der Hand zu weisen 😉

@ chanderegg:

Deine Selectstring soll keine Variablennamen aus deinem C# Code enthalten sondern nur '?' als Platzhalter für diese.

Als Beispiel habe Ich dir folgendes Statement gegeben:

"SELECT CustomerID, CompanyName FROM Customers WHERE Country = ? AND City = ?"

In deinem String darf nicht ein + C#Variablenname + stehen sondern für jede Variable oder Wert die du übergeben möchtest steht ein '?'

Bei dir also in etwa:

mySelectQuery = "UPDATE xc001 SET xccmt = ? WHERE xcprj = ? AND xcver = ? AND xctab = ? AND xccol = ?";

Greetz da kubi.

P.S.:
Wenn du einen Rückgabewert haben möchtest, also eine Antwort auf deine Frage ( Query ) solltest du Command.ExecuteScalar(); verwenden.

Zitat Doku :

Ruft einen einzelnen Wert (z. B. einen Aggregatwert) aus einer Datenbank ab.

Mehr dazu in der Doku unter OleDbCommand-Klasse