UpdateCommand Spalte nicht gefunden ?!?

  • C#
  • .NET (FX) 4.0

Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von OlafSt.

    UpdateCommand Spalte nicht gefunden ?!?

    Hallo Freunde,

    ich habe hier eine SQLAnywhere-Datenbank liegen und möchte nun per C# und OleDB darauf zugreifen. OleDB und untypisierte Datasets sind leider Pflicht - diese Art SQL-Server verfügt über ein "Feature", das die Nutzung typisierter Datasets oder gar des EF ausschließt :(

    Also habe ich hier einen OleDbDataAdapter, der wie folgt erzeugt wird:

    C#-Quellcode

    1. BootAdapter = new OleDbDataAdapter("SELECT KDNR,Schiffsname, ID FROM Bootsdaten", dbc.Conn);


    KDNR und Schiffsname sind zwei VarChars (20+50 Zeichen), ID ist ein Autoincrement-Integer, Identitätsspalte und Primary Key. Null Hexenwerk.

    Blöderweise erzeugt das UpdateCommand, das per OleDbCommandBuilder erzeugt wird, nicht das korrekte Update-Statement. da es mehrere Schiffe mit demselben Namen geben kann, wird ein Boot mit dem Namen "X" zwar editiert, aber alle anderen Boot, die auch "X" als Schiffsnamen haben, gleich mit. Die Identity-Spalte wird nicht berücksichtigt. Also habe ich mir gedacht, machste das UpdateCommand eben selbst:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname=@Schiffsname "+
    2. "WHERE ID=@ID", dbc.Conn);
    3. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50); //, "Schiffsname");
    4. UpdateCommand.Parameters.Add("@ID", OleDbType.Integer,4,"ID");


    Zum Test nur der Schiffsname drin. Lasse ich das laufen, gibts folgende Fehlermeldung:

    "Spalte @ID nicht gefunden". Natürlich nicht, die gibts auch nicht, steht ja auch hinter dem Gleichheitszeichen :cursing: Was mache ich denn nun falsch ? Ich seh da echt keinen Fehler und bin bestimmt mal wieder Betriebsblind.
    So, hatte endlich Zeit, mich des Problems weiter anzunehmen. Habe die Anregung aufgenommen:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname=@Schiffsname "+
    2. "WHERE ID=@Plock", dbc.Conn);
    3. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50); //, "Schiffsname");
    4. UpdateCommand.Parameters.Add("@Plock", OleDbType.Integer,4,"ID");


    Fehlermeldung: Spalte "@Plock" nicht gefunden :( :(
    kann auch sein, dass OleDb-Sql-Syntax anders ist. Von Access weiß ich das genau, also probierma:

    SQL-Abfrage

    1. UPDATE Bootsdaten SET Schiffsname=? WHERE ID=?
    Alles andere so lassen.
    ach vlt. auch nicht, weil

    C#-Quellcode

    1. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50);
    ist ja misteriös - dem Param müsste man doch einen String übergeben, oder?
    Da ist was dran, das sind ja Zeichenketten... Also flugs was geändert:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname='@Schiffsname', Bemerkung='@Bemerkung' "+
    2. "WHERE ID=@Plock", dbc.Conn);
    3. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50); //, "Schiffsname");
    4. UpdateCommand.Parameters.Add("@Bemerkung", OleDbType.VarChar, 500); //, "Bemerkung");
    5. UpdateCommand.Parameters.Add("@Plock", OleDbType.Integer,4,"ID");


    Fehlermeldung bleibt dieselbe. Gibt es irgendwo eine Möglichkeit, sich das tatsächlich zum SQL-Server geschickte Kommando anzusehen ? Vielleicht bringt uns das auf die Spur.
    Weil ich keinen Schimmer habe, wie ich die Parameter, die nun alle "?" heißen, in die Parameters-Collection hineinbekommen soll. UpdateCommand.Parameters.Add erwartet einen Namen für den Parameter :cursing:

    AddWithValue kann ich nicht benutzen - das soll ja schließlich im DataAdapter.Update alles passieren. Aber vermutlich habe ich wieder irgendwo eine Wissens-Lücke ;)

    Edit: Habe es mal mit Fragezeichen probiert:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname='?', Bemerkung='?' "+
    2. "WHERE ID=?", dbc.Conn);
    3. UpdateCommand.Parameters.Add("", OleDbType.VarChar, 50); //, "Schiffsname");
    4. UpdateCommand.Parameters.Add("", OleDbType.VarChar, 500); //, "Bemerkung");
    5. UpdateCommand.Parameters.Add("", OleDbType.Integer,4,"ID");


    Das hat was verändert, die Fehlermeldung ist nun: Nicht genügend Werte für Hostvariablen.

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

    ah - dann wars also zu einfach. Aber sag das doch.
    Ich bin immer sofort beleidigt, wenn man was ignoriert, was ich sage. Das wird auch nicht besser bei mir.
    Wie gesagt - zu einfach - ich meinte es genau, wie ichs gesagt habe:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname=?, Bemerkung=? WHERE ID=?", dbc.Conn);
    2. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50); //, "Schiffsname");
    3. UpdateCommand.Parameters.Add("@Bemerkung", OleDbType.VarChar, 500); //, "Bemerkung");
    4. UpdateCommand.Parameters.Add("@Plock", OleDbType.Integer,4,"ID");

    (Und ich versprech nicht, dasses jetzt geht)

    ErfinderDesRades schrieb:

    ah - dann wars also zu einfach. Aber sag das doch.
    Ich bin immer sofort beleidigt, wenn man was ignoriert, was ich sage. Das wird auch nicht besser bei mir.


    Ach so. Ist schwer, sowas abzustellen, ich merks mir für die Zukunft :)


    Wie gesagt - zu einfach - ich meinte es genau, wie ichs gesagt habe:

    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname=?, Bemerkung=? WHERE ID=?", dbc.Conn);
    2. UpdateCommand.Parameters.Add("@Schiffsname", OleDbType.VarChar, 50); //, "Schiffsname");
    3. UpdateCommand.Parameters.Add("@Bemerkung", OleDbType.VarChar, 500); //, "Bemerkung");
    4. UpdateCommand.Parameters.Add("@Plock", OleDbType.Integer,4,"ID");

    (Und ich versprech nicht, dasses jetzt geht)


    Hab ich versucht. Auch mit Tüddelchen umme Fragezeichen rum und so Zeug. Immer dieselbe Meldung: Nicht genügend Werte für Hostvariablen.

    Kann es sein, das ein manuelles UpdateCommand nicht funktioniert, wenn man OleDbAdapter.Update(myDataSet, MyTableName) benutzt ? Dann stecke ich in größeren Problemen... Andere Frage: Ich benutze auch ein manuelles SelectCommand, das natürlich das dutzend Tabellenspalten abfragt. Müssen die abgefragten Tabellenspalten im SelectCommand mit denen im UpdateCommand korrelieren ?

    Mit einem CommandBuilder habe ich es als erstes probiert. Funktionierte auch super, bis wir merkten, das ALLE Datensätze mit gleichlautenden Schiffsnamen verändert wurden. man bearbeitet also das Boot mit Namen "Möwe" und alle Boote mit Namen "Möwe" wurden geändert, völlig egal, welches Datum man nun im Datensatz geändert hat. Nein, Schiffsname ist KEIN Primärindex-Feld.

    Ich habe also ein Feld namens "ID" hinzugefügt, dieses als INT deklariert, zu einem Autoincrement-Feld gewandelt und einen Primärindex draufgesetzt. Damit sollte das Thema endgültig vom Tisch sein, habe ich gedacht - Falsch gedacht, es hat nämlich rein gar nichts geändert.

    So langsam geht mir das Latein aus, zumal ich auch nicht sehen kann, was tatsächlich zum SQL-Server gelangt. UpdateCommands mit CommandBuilder kann ich nirgendwo sehen (im DataAdapter ist das alles null)

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

    tja, also meine Commandbuilder kommen damit klar.
    Und ja, natürlich setzen sie vorraus, dasses einen Primkey gibt - ich glaub, andernfalls generieren die erst garkein UpdateCommand.

    Also tippe ich darauf, dass in eure Db was faul ist.
    Ist ja auch interessant, dasser nur die Schiffe mit dem angegebenen Namen ändert - da hatter offsichtlich die Namespalte für relevant gehalten, und den Where-Abschnitt entsprechend generiert.

    Zur not mach Versuche mit einer anderen Db. Kannst ja sogar eine nehmen aus ieinem meiner Db-tuts.
    Ahoi,
    der MSDN nach, erwartet OleDbCommand wohl die Parameter mit ?.Hast du denn wirklich den Command so wie du es hier gepostet hast versucht?

    OlafSt schrieb:


    C#-Quellcode

    1. OleDbCommand UpdateCommand = new OleDbCommand("UPDATE Bootsdaten SET Schiffsname='?', Bemerkung='?' "+
    2. "WHERE ID=?", dbc.Conn);
    3. UpdateCommand.Parameters.Add("", OleDbType.VarChar, 50); //, "Schiffsname");
    4. UpdateCommand.Parameters.Add("", OleDbType.VarChar, 500); //, "Bemerkung");
    5. UpdateCommand.Parameters.Add("", OleDbType.Integer,4,"ID");



    Versuch es mal ohne ' um die ?.
    Grüße Manu

    Was Gott dem Menschen erspart hat, kann der Computer.
    Billy ©, (*1932), Schweizer Aphoristiker
    Quelle: www.Aphorismen.de
    Ich hab den Fehler entdeckt :cursing: :cursing:

    Mit dem CommandBuilder ist alles okay, der funktionierte tadellos - aber meine Anzeige nicht. Da sich hinter mancher Kundennummer durchaus mehr als ein Schiff verbergen kann, habe ich eine Combobox, die mit den Schifsnamen gefüllt wird. Man selektiert dann einfach aus der Liste ein Schiff und sieht prompt seine Daten.

    Ist nur blöd, wenn man zum Anzeigen der Daten NUR den Schiffsnamen heranzieht... Man sieht also immer nur die Daten des ersten in der DB gefundenen Schiffs. Mann, bin ich manchmal umnachtet...

    Beim Abspeichern fand sich dann ein ähnlicher Fehler, auch hier wurde nur der Schiffsname zum Suchen benutzt.

    Problem also gelöst. Danke für eure Mithilfe !