Datentypkonflikt

  • VB.NET
  • .NET (FX) 4.5–4.8

Es gibt 29 Antworten in diesem Thema. Der letzte Beitrag () ist von Yanbel.

    Datentypkonflikt

    Hi,
    hab ein problem mit einem Datentypkonflikt kann mir evtl jemand sagen wo mein Fehler liegt?

    VB.NET-Quellcode

    1. Public Property Softwareid As Integer
    2. Public Property bslicenses As BindingSource
    3. Private Sub LicenseEdit_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    4. Dim cb11 As New OleDbCommandBuilder(dapcs2)
    5. Dim cmd As New OleDbCommand
    6. 'cmd.Parameters.AddWithValue("@sofid", Softwareid) MIT DEM PARAMETER GEHTS AUCH NICHT
    7. cmd.CommandText = "Select * From Licenses where software_id = '%" & Softwareid & "%'"
    8. cmd.Connection = con
    9. dapcs2.SelectCommand = cmd
    10. dapcs2.Fill(dtcomboSoftware)
    11. cbblicense.DataSource = dtcomboSoftware
    12. cbblicense.DisplayMember = "license"


    softwareid ist = DgvSoftware.Currentrow.Cells(0).Value
    Es sollte ja eigentlich alles in Ordnung sein, vergleiche ja Integer mit Integer oder nicht?


    Wäre schön wenn jemand helfen kann. Danke im vorraus :D.

    Mfg Fabian

    CodeTags korrigiert ~VaporiZed

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

    fabimaurice schrieb:


    cmd.CommandText = "Select * From Licenses where software_id = '%" & Softwareid & "%'"


    Zunächst einmal ist das Prozentzeichen an dieser Stelle falsch, dass brauchst du nur für einen Abgleich mit dem Operator LIKE. Dein Datentypfehler kommt aber durch die Anführungszeichen vor und hinter der ID. Dadurch wird dein Integer-Wert zu einen CHAR. Korrekt wäre an dieser Stelle:

    VB.NET-Quellcode

    1. cmd.CommandText = "Select * From Licenses where software_id = " & CStr(Softwareid)


    oder besser parametrisiert:

    VB.NET-Quellcode

    1. cmd.CommandText = "Select * From Licenses where software_id = @sofid"


    Parameter fügst du so hinzu:

    VB.NET-Quellcode

    1. cmd.Parameters.Add("@sofid", SqlDbType.Int).Value = Softwareid




    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    @Yanbel
    Das scheint aufjedenfall schonmal richtig zu sein. Würde dir aber empfehlen beim hinzufügen von Parametern AddwithValue zu verwenden wenn ich das ganze richtig verstehe ist Add die veraltete Version aber belehre mich gerne eines besseren falls nein
    Funktioniert nun alles außer wenn ich mein Datatable updaten will während ich die Form schließe. In jenem Fall, kommt diese Fehlermeldung:
    System.InvalidOperationException: "Die OleDbCommand.Prepare-Methode erfordert, dass für alle Parameter explizit ein Typ festgelegt wird."


    Hast du dafür auch eine Lösung :) ?

    würde mich freuen^^


    Übrigens Entschuldigung fürs lange warten. Waren Betriebsferien:)

    Mit freundlichen Grüßen
    Fabimaurice

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

    Schick mal die SQL-Update Query, dann schauen wir uns das mal an.

    Ich vermute das lässt sich einfach beheben, in dem du anstelle von cmd.Parameters.Add lieber cmd.Parameters.AddWithValue verwendest, wenn eine Variable mit Nothing übergeben wird. Aber lass uns mal schauen.

    EDIT: Probier mal sowas:

    VB.NET-Quellcode

    1. If Variable is Nothing Then
    2. cmd.Parameters.AddWithValue("@Variable", DBNull.Value)
    3. Else
    4. cmd.Parameters.Add("@Variable", SqlDbType.Int).Value = Variable
    5. EndIf


    Und damit sollte deine Frage auch beantwortet sein. Add ist keinesfalls die veraltete Methode. Du verwendest Add um Variablen mit expliziten Typen an die Datenbank zu übergeben. Während AddWithValue Strings immer als Unicode String sprich als NVARCHAR übergibt. Das ist zwar grundsätzlich auch in Ordnung aber glaub mir beides hat seine Darseinsberechtigung. ;)


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    Dieser Beitrag wurde bereits 6 mal editiert, zuletzt von „Yanbel“ ()

    Und auf die Klasse DaEditLicense hast du keinen Zugriff? Ihr verwendet vermutlich für jede Datenbanktabelle DataModel- und DataAccess-Klassen, oder? Dein Praefix Da vor EditLicense deutet zumindest darauf hin. Aber dann verstehe ich nicht ganz wieso das beim Update mit einem solchen Fehler abschmiert und wieso du einen SQL-Zugriff schreiben musst. Wieso habt ihr keine SQL-Klasse die den Aufbau der Verbindung und die SQL-Parametriesierung übernimmt?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    @Yanbel
    Da steht für DataAdapter ist ein normaler OledBDataAdapter. Tut mir leid war vllt etwas falsch formuliert. Und alles was du erwähnt hast nutze ich nicht da es ein Übungsprogramm ist. Hab ja gerade erst meine Ausbildung begonnen :). Aber trzdm danke das du dir soviele Gedanken machst um mir zu helfen :).


    Und das mit Variable is nothing dürfte theoretisch nicht gehen da Softwareid ein Integer ist ich probiers aber kurz

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

    Das ist kein Problem. Um dir die Arbeit zu erleichtern würde ich das Konstrukt ändern. Schreib dir eine allgemeine SQL-Klasse die den Zugriff auf deine Daten regelt. In der Klasse sollte folgendes enthalten sein:

    eine Funktion in der zu übergebene Variablen in SQL-Parameter umwandelt werden.

    eine Funltion zum Lesen von Daten in der du Parameter und eine Query übergibst

    eine Funktion zum Schreiben an die du ebenfalls Parameter und Query übergibst.

    Die Parameter kannst du in beliebiger Form übergeben beispielsweise als List(of KeyValuePair(of String, Object)). Hat gegenüber Dictionaries den Vorteil, dass eine generische Liste in vollem Umfang LINQ unterstützt.

    Die Funktion zum Lesen und Schreiben enthält den Auf- und Abbau deiner SQL-Connection. Dann brauchst du das Gedöns nicht für jeden Datenbankzugriff neu zu schreiben.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    fabimaurice schrieb:


    daeditlicense.update(dtlicenses)


    Du übergibst keine Parameter an die Methode. Ich kann dir hier nicht helfen wenn ich nicht weiß was sich in der DaEditLicense-Klasse befindet. Ich muss schon sehen, welche Query du an die Datenbank übergibst. Diese scheint ja Parameter zu enthalten, die nicht ausreichend typisiert wurden. was genau macht denn die Update-Methode? Und gibt es vielleicht Überladungen, in denen du Parameter übergeben kannst?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

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

    @Yanbel
    Ich übergebe die Werte an Properties SoftwareID ist als Integer festgelegt und hat den Wert von Spalte Null im DataGridView der Software.
    Also ist theoretisch SoftwareID = Form1.dgvSoftware.CurrentRow.Cell(0).Value (Ja ich weiß Parameter übergeben und so nutzen macht mehr Sinn für Formübergreifendes arbeiten ändere ich gerade schon ab)
    Die Update Methode Aktuallisiert mithilfe des Commandbuilders die abgeänderten Daten in die Datenbank.
    @fabimaurice
    Ist ja erstmal nicht schlimm, dass du keine Parameter benutzt. Ist ja kein Must-Have für ein Übungsprogramm ;) Mit CurrentRow bin ich immer vorsichtig, dass liefert häufig nicht die Zeile, die du erwartest. Kommt immer auf das Event an in dem du die Zeile abfragst.

    Schau mal bitte wo genau du die Methode cmd.Prepare() aufrufst und stell mal bitte den Code der betreffenden Methode hier rein.


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

    fabimaurice schrieb:


    System.InvalidOperationException: "Die OleDbCommand.Prepare-Methode erfordert, dass für alle Parameter explizit ein Typ festgelegt wird."


    Naja, das ist die Methode die den Fehler auslöst. Ich kenne deine Architektur nicht, aber denn du die Methode nicht aufrufst, dann wird die vermutlich in der DaEditLicense.Update-Methode aufgerufen. Kannst du den Quellcode der Methode einsehen? Was passiert denn wenn du den Textcursor auf das Wort Update setzt und F12 drückst?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    Okay, wenn du nur die Metadaten siehst, dann liegt die Methode in einer Library und ist für dich nicht zugreifbar. Da kommen wir dann nicht weiter

    Was ist dtlicense für ein Typ? DataTable? Weil du ja meintest du würdest Properties füllen?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.
    @Yanbel

    Jep das ist ein Datatable war oben aber eher als Beispiel gedacht weil ich den Name nicht im Kopf hatte. In diesem fall ist es
    dapcs2.update(dtcombosoftware)
    Ich bekomme ja von der Property die ID aus dem Dgv der gerade ausgewählten Lizenz diese Vergleiche ich im cmd Befehl mit der Db id und lasse nur die dazu passenden Daten laden mit diesen Daten befülle ich dann das Datatable und update am ende über den Dapcs2 DataAdapter.

    Hoffe zusammengefasst genug :D Aber verständlich

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

    @Yanbel
    Zuerst auch wenn es noch nicht gelöst ist Vielen herzlichen Dank das du dir für mich soviel Zeit nimmst.
    Und hier der komplette Code des closing Events ist ja im Prinzip nicht allzu viel^^

    Quellcode

    1. dtcombosoftware.GetChanges()
    2. If dtcombosoftware.GetChanges IsNot Nothing Then
    3. If MessageBox.Show("Do you want to save your changes?", "", MessageBoxButtons.YesNo, MessageBoxIcon.Question) = DialogResult.Yes Then
    4. dapcs2.Update(dtcombosoftware)
    5. End If
    6. End If
    7. Form1.Show()
    8. Close()
    Gerne.

    Der Code im Close ist soweit i.O. ich fürchte wir müssen weiter schauen.

    Du verwendest ja den selben Adapter wie in der Read Methode ohne ihn neu zu initialisieren. Initialisier den mal bitte neu und teste dann nochmal. Ich denke mal dass der Adapter noch irgendwo die Parameter drin hat.

    Also oben drüber

    VB.NET-Quellcode

    1. dapcs2 = New OleDbDataAdapter 'natürlich mit den entsprechenden Parametern

    Und dann der restliche Close Code

    EDIT: Augenblick, Update ist dann ja eine Methode des OleDBAdapters und nicht wie ich vermutet hatte eine Methode aus einer eigenen dll deines Betriebs. Woher weiß denn der Adapter in welche Tabelle er welche Werte schreiben soll. Wo ist die dazugehörige Query? Oder versuchst du gerade mit dem Command aus dem FormLoad in die Datenbank zu schreiben?


    Ein Computer wird das tun, was du programmierst - nicht das, was du willst.

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