Announcement

Collapse
No announcement yet.

DbDataAdapter-InsertCommand liefert Exception

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DbDataAdapter-InsertCommand liefert Exception

    Hallo,
    ich fange jetzt an, möglichst <b>DB-unabhängig unter NET 2.0 (#D für Firebird)</b> zu programmieren. SELECT für <u>DataSet und DataGridView</u> klappt; aber mein erster Versuch zur <b>"automatischen Speicherung"</b> geht teilweise schief. Den Ablauf und Zusammenhang verstehe ich nicht und bitte deshalb erst mal um Hinweise, auf welchem Weg ich den Fehler eingrenzen und wonach ich suchen kann.

    <u>DB-Umgebung und IDE</u>
    FB 2.0 RC4, FB-Net-Provider 2.0 RC1
    NET 2.0 mit #D 2.0
    halbautomatisch erzeugte xsd-Datei, typisiertes DataSet durch xsd.exe

    <u>Ausgangspunkt (mit den wichtigsten Befehlen)</u>
    dataFactory = DbProviderFactories.GetFactory("FirebirdClient");
    da = dataFactory.CreateDataAdapter();
    // SelectCommand erzeugen
    da.SelectCommand = dataFactory.CreateCommand();
    da.SelectCommand.Connection = conn;
    da.SelectCommand.CommandText = "SELECT * FROM " + tbl.TableName;
    cmdb = dataFactory.CreateCommandBuilder();
    cmdb.DataAdapter = da;
    // jetzt Befehl ausführen
    da.Fill(ds, tbl.TableName);
    da.InsertCommand = cmdb.GetInsertCommand();
    da.DeleteCommand = cmdb.GetDeleteCommand();
    da.UpdateCommand = cmdb.GetUpdateCommand();

    Nach <u>Neuaufnahme eines Datensatzes</u> im DataSet wollte ich diesen sofort in die DB übertragen (testweise):

    try {
    da.Update(tbl);
    } catch (fb.FbException ex) {
    MessageBox.Show(ex.Message, "Firebird-Exception");
    } catch (Exception ex) {
    MessageBox.Show(ex.Message, "Allgemeine Exception");
    }

    Dabei bekomme ich immer wieder <u>Fehlermeldungen:</u>

    1. Versuch mit <b>FbException:</b> "validation error for column JAHR_GEB, value ' '" (d.h. 4 Leerzeichen). Dabei handelt es sich um ein CHAR(4)-Feld (NULL erlaubt).

    2. Versuch mit Feldinhalt "1763" mit allgemeiner <b>Exception:</b> "ArgumentNullException - 'dataType'-Argument darf nicht null sein." Trotzdem wurde der Datensatz übertragen (wie ich mit IBExpert festgestellt habe).

    3. Versuch (nach manueller Löschung) lieferte den gleichen Fehler.

    4. Versuch (dito) war <b>erfolgreich.</b>

    Der #D-Debugger gab zusätzlich Hinweis auf die letzten Maßnahmen:
    Update() // wahrscheinlich der Auslöser
    UpdateFromDataTable() // eine protected-Maßnahme?
    Update() // ??

    Wer kann mir Tipps geben, wo ich die Umstände des Fehlers suchen kann oder welche Informationen ich/Ihr benötigt? Danke! Jürgen

  • #2
    Hallo,
    ab dem .NET Framework 2.0 kann XSD.EXE <b>keinen</b> vollständigen TableAdapter generieren (TableAdapter = typisiertes DataSet + typisierter DataAdapter), sondern nur ein typisiertes DataSet (also der Funktionsumfang von .NET 1.x). Die Anbindung an den TableAdapter ist nun Aufgabe der Entwicklungsumgebung (siehe Visual Studio 2005).

    Das DataSet speichert je Feld eines Datensatzes sowohl den alten (original von SELECT ausgelesen) Wert als auch den neuen (vom Programm/Benutzer eingetragenen) Wert (siehe <b>System.Data.DataRowVersion</b> in Verbindung mit der "Original_"-Syntax). Bei der Übergabe der Werte vom DataSet an die Parameter der INSERT-/UPDATE-/DELETE-Anweisung muss also jeweils der "richtige" Schalter verwendet werden, damit der entsprechende korrekte Wert zugewiesen wird. Die Wizards von Visual Studio 2005 erledigen diesen Job automatisch, so dass ein Entwickler mit diesen Zusammenhängen nicht mehr in Berührung kommt.

    Wenn es keinen Wizard gibt, müssen alle diese Zuweisungen von Hand nachvollzogen werden.

    Beispiel (VS2005-Wizard):

    <div style="font-family: Courier New; font-size: 10pt; color: black; background: white; border-top: windowtext 1pt solid; padding-top: 0pt; border-left: windowtext 1pt solid; padding-left: 0pt; border-right: windowtext 1pt solid; padding-right: 0pt; border-bottom: windowtext 1pt solid; padding-bottom: 0pt;"><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; [System.Diagnostics.<span style="color: teal;">DebuggerNonUserCodeAttribute</span>()]</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">private</span> <span style="color: blue;">void</span> InitAdapter() {</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter = <span style="color: blue;">new</span> System.Data.SqlClient.SqlDataAdapter();</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; System.Data.Common.DataTableMapping tableMapping = <span style="color: blue;">new</span> System.Data.Common.DataTableMapping();</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.SourceTable = <span style="color: maroon;">"Table"</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.DataSetTable = <span style="color: maroon;">"UsrTbl"</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.ColumnMappings.Add(<span style="color: maroon;">"usrtbl_id"</span>, <span style="color: maroon;">"usrtbl_id"</span>);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.ColumnMappings.Add(<span style="color: maroon;">"wert"</span>, <span style="color: maroon;">"wert"</span>);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.ColumnMappings.Add(<span style="color: maroon;">"datum"</span>, <span style="color: maroon;">"datum"</span>);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.ColumnMappings.Add(<span style="color: maroon;">"benutzer"</span>, <span style="color: maroon;">"benutzer"</span>);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; tableMapping.ColumnMappings.Add(<span style="color: maroon;">"ts"</span>, <span style="color: maroon;">"ts"</span>);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.TableMappings.Add(tableMapping);</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand = <span style="color: blue;">new</span> System.Data.SqlClient.SqlCommand();</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand.Connection = <span style="color: blue;">this</span>.Connection;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand.CommandText = <span style="color: maroon;">"DELETE FROM [dbo].[UsrTbl] WHERE (([usrtbl_id] = @Original_usrtbl_id) AND ([ts] ="</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">" @Original_ts))"</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand.CommandType = System.Data.CommandType.Text;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@Original_usrtbl_id"</span>, System.Data.SqlDbType.Int, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"usrtbl_id"</span>, System.Data.DataRowVersion.Original, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.DeleteCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@Original_ts"</span>, System.Data.SqlDbType.Timestamp, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"ts"</span>, System.Data.DataRowVersion.Original, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand = <span style="color: blue;">new</span> System.Data.SqlClient.SqlCommand();</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.Connection = <span style="color: blue;">this</span>.Connection;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.CommandText = <span style="color: maroon;">"INSERT INTO [dbo].[UsrTbl] ([wert], [datum], [benutzer]) VALUES (@wert, @datum, @"</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">"benutzer);\r\nSELECT usrtbl_id, wert, datum, benutzer, ts FROM UsrTbl WHERE (usrtb"</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">"l_id = SCOPE_IDENTITY())"</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.CommandType = System.Data.CommandType.Text;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@wert"</span>, System.Data.SqlDbType.VarChar, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"wert"</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@datum"</span>, System.Data.SqlDbType.SmallDateTime, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"datum"</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.InsertCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@benutzer"</span>, System.Data.SqlDbType.VarChar, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: blue;">null</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand = <span style="color: blue;">new</span> System.Data.SqlClient.SqlCommand();</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Connection = <span style="color: blue;">this</span>.Connection;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.CommandText = <span style="color: maroon;">"UPDATE [dbo].[UsrTbl] SET [wert] = @wert, [datum] = @datum, [benutzer] = @benutze"</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">"r WHERE (([usrtbl_id] = @Original_usrtbl_id) AND ([ts] = @Original_ts));\r\nSELECT"</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">" usrtbl_id, wert, datum, benutzer, ts FROM UsrTbl WHERE (usrtbl_id = @usrtbl_id)"</span> +</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: maroon;">""</span>;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.CommandType = System.Data.CommandType.Text;</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@wert"</span>, System.Data.SqlDbType.VarChar, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"wert"</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@datum"</span>, System.Data.SqlDbType.SmallDateTime, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"datum"</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@benutzer"</span>, System.Data.SqlDbType.VarChar, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: blue;">null</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@Original_usrtbl_id"</span>, System.Data.SqlDbType.Int, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"usrtbl_id"</span>, System.Data.DataRowVersion.Original, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@Original_ts"</span>, System.Data.SqlDbType.Timestamp, 0, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"ts"</span>, System.Data.DataRowVersion.Original, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; <span style="color: blue;">this</span>._adapter.UpdateCommand.Parameters.Add(<span style="color: blue;">new</span> System.Data.SqlClient.SqlParameter(<span style="color: maroon;">"@usrtbl_id"</span>, System.Data.SqlDbType.Int, 4, System.Data.ParameterDirection.Input, 0, 0, <span style="color: maroon;">"usrtbl_id"</span>, System.Data.DataRowVersion.Current, <span style="color: blue;">false</span>, <span style="color: blue;">null</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>, <span style="color: maroon;">""</span>));</p><p style="margin: 0px;">&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp; }</p></div&gt

    Comment


    • #3
      Danke, Herr Kosch,

      dies hilft mir beim Verständnis und dem weiteren Vorgehen.

      <u>Ad-hoc</u> werde ich das typisierte DataSet um entsprechende Adapter-Behandlung gemäß Ihrem Muster erweitern. Da ich sowieso eine Klasse zum Austausch zwischen Programmablauf und DataSet habe, passt dies wohl dort hinein.

      <u>Dauerhaft</u> werde ich mir den Wizard von VC# vornehmen. (In #D sind Wizards nur spärlich enthalten; aber 'irgendwie' habe ich mit #D ein besseres Arbeitsgefühl als mit VC#.

      Comment


      • #4
        Eine Ergänzung: Als schnelle adhoc-Lösung (ohne Erweiterung des DataAdapters) funktioniert, für jedes string-Feld festzulegen:

        sFeldinhalt = sFeldinhalt.Trim();
        if (sFeldinhalt == "")
        sFeldinhalt = null;

        Das geht natürlich nur bei Feldern, die null sein dürfen. Jürge

        Comment


        • #5
          Eine weitere Ergänzung: Beim Firebird-Support habe ich in anderem Zusammenhang eine klare Erläuterung für meinen Fehler erhalten: Ein <b>CHAR-Feld erwartet <u>genau</u> die festgelegte Anzahl von Zeichen</b> (in meinem Fall 4). Wenn eine andere Anzahl von Zeichen (z.B. 0) kommt, gibt es einen Fehler; deshalb funktioniert die Übergabe des 'Wertes' null

          Comment

          Working...
          X