OleDataAdapter gibt leere Tabelle zurück statt einer gefüllten

  • VB.NET
  • .NET 5–6

Es gibt 11 Antworten in diesem Thema. Der letzte Beitrag () ist von Amro.

    OleDataAdapter gibt leere Tabelle zurück statt einer gefüllten

    Hallo,

    ich habe ein Verständnisproblem.

    Ich habe diese Funktion

    VB.NET-Quellcode

    1. Public Function CurrentProjectTable(tblProjectID As Long, Optional visible As TaskVisible = TaskVisible.open) As DataTable
    2. Dim strVisible As String = ""
    3. If visible > TaskVisible.all Then
    4. strVisible = " AND t.finished = @finished"
    5. End If
    6. Dim sql As String = baseSQL & " AND t.tblProjectID = @tblProjectID" & strVisible
    7. Dim dt As New DataTable
    8. Using conn As New OleDbConnection(connString)
    9. Dim comm As New OleDbCommand(sql, conn)
    10. If visible > TaskVisible.all Then
    11. comm.Parameters.Add("@finished", OleDbType.Boolean).Value = IIf(visible = TaskVisible.open, False, True)
    12. End If
    13. comm.Parameters.Add("@tblProjectID", OleDbType.Integer).Value = tblProjectID
    14. Debug.Print(GetFullCommandSQL(comm))
    15. Using da As New OleDbDataAdapter()
    16. da.SelectCommand = comm
    17. da.Fill(dt)
    18. End Using
    19. End Using
    20. Return dt
    21. End Function


    Wenn ich die Funktion so

    Quellcode

    1. CurrentProjectTable(1, ClsToDoDB.TaskVisible.all)
    aufrufe bekomme ich wie erwartet einen Datensatz in der Tabelle.
    Der SQL Code aus Zeile 15 sieht so aus:

    SQL-Abfrage

    1. SELECT t.tblToDoID, t.DayDate, t.Task, t.DueDate, t.finished, t.FinishDate, t.PriorityID, u.Username, p.Project, t.tblProjectID, t.tblUserID
    2. FROM tblToDo as t, tblUser as u, tblProject as p
    3. WHERE t.tblUserID = u.tblUserID AND t.tblProjectID = p.tblProjectID AND t.Actual = True AND t.tblProjectID = 1

    Der Aufruf CurrentProjectTable(1, ClsToDoDB.TaskVisible.finished) ergibt eine leere Tabelle.
    Wenn ich den SQL-Code (aus Zeile 15) direkt in Access ausführe erhalte ich eine Tabelle.

    SQL-Abfrage

    1. SELECT t.tblToDoID, t.DayDate, t.Task, t.DueDate, t.finished, t.FinishDate, t.PriorityID, u.Username, p.Project, t.tblProjectID, t.tblUserID
    2. FROM tblToDo as t, tblUser as u, tblProject as p
    3. WHERE t.tblUserID = u.tblUserID AND t.tblProjectID = p.tblProjectID AND t.Actual = True AND t.tblProjectID = 1 AND t.finished = True


    Warum bekomme ich im zweiten Fall kein Ergebnis in VB?
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

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

    @INOPIAE Was kommt zurück, wenn Du "SELECT *" machst, also alles ausliest?
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Hallo Rod, ich verstehe Deine Frage nach Select * nicht in dem Zusammenhang.
    Wenn ich das SQL-Statement ohne " AND t.finished = True" nutze bekomme ich ein Ergebnis mit dem Zusatz bekomme ich in VB kein Ergebnis in Access aber sehr wohl.
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

    INOPIAE schrieb:

    AND t.finished = True
    Was ist das für eine Datenbank? Ich weiß gar nicht ob mySql True MsSql tut das zumindest nicht, Boolean sind dort bits und repräsentiert als 1 oder 0

    Da du keine Fehlermeldung bekommst, solltest du die Sqls selbst mal nachgucken.
    Da der einzige Unterschied nur diese t.finished ist, wäre aber die erste Vermutung, dass es keine Datensätze mit `finished = true` gibt in der Tabelle.

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

    INOPIAE schrieb:

    ich verstehe Deine Frage nach Select * nicht in dem Zusammenhang.
    Wenn mit * alles kommt, ist Dein SQL-String falsch.
    Falls Du diesen Code kopierst, achte auf die C&P-Bremse.
    Jede einzelne Zeile Deines Programms, die Du nicht explizit getestet hast, ist falsch :!:
    Ein guter .NET-Snippetkonverter (der ist verfügbar).
    Programmierfragen über PN / Konversation werden ignoriert!
    Es scheint da ein Übermittlungsproblem von VB über System.Data.OleDb zu MS Access zu geben.

    Weder comm.Parameters.Add("@finished", OleDbType.Boolean).Value = IIf(visible = TaskVisible.open, False, True) noch comm.Parameters.Add("@finished", OleDbType.TinyInt).Value = IIf(visible = TaskVisible.open, 0, -1) scheint zu gehen. Wenn ich die Bedingung hart in das SQL reinschreibe gehts.

    VB.NET-Quellcode

    1. Public Function CurrentProjectTable(tblProjectID As Long, Optional visible As TaskVisible = TaskVisible.open) As DataTable
    2. Dim strVisible As String = ""
    3. Select Case visible
    4. Case TaskVisible.finished
    5. strVisible = " AND t.finished = True"
    6. Case TaskVisible.open
    7. strVisible = " AND t.finished = False"
    8. End Select
    9. Dim sql As String = baseSQL & " AND t.tblProjectID = @tblProjectID" & strVisible
    10. Dim dt As New DataTable
    11. Using conn As New OleDbConnection(connString)
    12. Dim comm As New OleDbCommand(sql, conn)
    13. If visible > TaskVisible.all Then
    14. 'comm.Parameters.Add("@finished", OleDbType.TinyInt).Value = IIf(visible = TaskVisible.open, 0, -1)
    15. End If
    16. comm.Parameters.Add("@tblProjectID", OleDbType.Integer).Value = tblProjectID
    17. Using da As New OleDbDataAdapter()
    18. da.SelectCommand = comm
    19. da.Fill(dt)
    20. End Using
    21. End Using
    22. Return dt
    23. End Function
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).
    Ich hab kaum Erfahrung mit SQL. Gibt es die Möglichkeit, den fertigen SQL-Commandtext zu vergleichen? Also hardcoded vs. CommandBuilder

    btw: IIf(visible = TaskVisible.open, False, True) :?:
    IIF() -> If()
    aber einfach einfacher:
    --> comm.Parameters.Add("@finished", OleDbType.Boolean).Value = visible <> TaskVisible.open
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Ja mit diesem Code kann das SQL-Statement vom OleDBCommand ausgegeben werden.

    VB.NET-Quellcode

    1. ' Function to get the text send to Database from OleDbCommand with parameters
    2. ' use: Debug.Print(GetFullCommandSQL(comm))
    3. Public Function GetFullCommandSQL(cmd As OleDbCommand) As String
    4. Dim sql As String = cmd.CommandText
    5. For Each p As Data.Common.DbParameter In cmd.Parameters
    6. If sql.Contains(p.ParameterName) AndAlso p.Value IsNot Nothing Then
    7. If p.Value.GetType Is GetType(String) Then
    8. sql = sql.Replace(p.ParameterName,
    9. String.Format("'{0}'", p.Value.ToString))
    10. Else
    11. sql = sql.Replace(p.ParameterName, p.Value.ToString)
    12. End If
    13. End If
    14. Next
    15. Return sql
    16. End Function


    Das SQL-Statement sieht sowohl mit Parameter und hardcoded identisch aus. Es verhält sich nur anders.

    SQL-Abfrage

    1. SELECT t.tblToDoID, t.DayDate, t.Task, t.DueDate, t.finished, t.FinishDate, t.PriorityID, u.Username, p.Project, t.tblProjectID, t.tblUserID FROM tblToDo as t, tblUser as u, tblProject as p WHERE t.tblUserID = u.tblUserID AND t.tblProjectID = p.tblProjectID AND t.Actual = True AND t.tblProjectID = 1 AND t.finished = True
    NB. Es ist doch schön, wenn man lesbare Namen vergibt. Siehe auch [VB.NET] Beispiele für guten und schlechten Code (Stil).

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

    VaporiZed schrieb:

    Ich hab kaum Erfahrung mit SQL. Gibt es die Möglichkeit, den fertigen SQL-Commandtext zu vergleichen? Also hardcoded vs. CommandBuilder
    nach meinem letzten Kenntnisstand geht das nicht, wenn der Parameter nicht funktioniert kann man das nicht einsehen. Der Befehl und der Parameter werden separat übergeben und erst von der Datenbank selbst zusammen gebastelt. Zumindest bei MsSql aber Access kommt ja auch von Microsoft.
    na das ist jdfs kein gültiges Sql:

    INOPIAE schrieb:

    Das SQL-Statement

    SQL-Abfrage

    1. SELECT t.tblToDoID, t.DayDate, t.Task, t.DueDate, t.finished, t.FinishDate, t.PriorityID, u.Username, p.Project, t.tblProjectID, t.tblUserIDFROM tblToDo as t, tblUser as u, tblProject as pWHERE t.tblUserID = u.tblUserID AND t.tblProjectID = p.tblProjectID AND t.Actual = True AND t.tblProjectID = 1 AND t.finished = True