Datei (Pdf) in SQL und wieder raus, kann doch nicht so schwer sein..

  • VB6
  • .NET 7–8

Es gibt 1 Antwort in diesem Thema. Der letzte Beitrag () ist von Haudruferzappeltnoch.

    Datei (Pdf) in SQL und wieder raus, kann doch nicht so schwer sein..

    Guten Abend zusammen

    Ich sitze hier seit einer guten Woche immer wieder an einer Knacknuss.

    Eine Debatte ob es Sinnvoll ist eine Datei in einem Server abzulegen möchte ich hier nicht lostreten.

    Ich möchte einfach gerne eine Pdf-Datei von meinem Pc in einen MsSql Server ablegen und auch wieder auslesen und auf meinen PC zurück schreiben.

    Ich möchte in meiner kleinen Privaten Visual Studio (vb) Anwendung nur Code habe denn ich auch versehe.
    Somit habe ich Unmengen Youtube Videos, Foren Einträge und Herangehensweisen gelesen.
    Die Herangehensweise habe ich verstanden und das dies mit verschiedenen Werkzeugen (FileStream u.s.w.) zu bewerkstelligen ist.

    Erstaunlich ist, das immer wieder gezeigt wird wie die Datei im Sql gespeichert werden kann. Das Herauslesen der Datei aus den Sql wird selten gezeigt und muss folglich Kinderleicht sein... aber genau an diesem Teil hapert es.

    Folgendes geht, lesen und schreiben (ohne MsSql)

    Visual Basic-Quellcode

    1. Dim bytes As Byte() = File.ReadAllBytes("C:\Temp\Test.pdf")
    2. My.Computer.FileSystem.WriteAllBytes("C:/Temp/Test2.pdf", bytes, True)


    Weiter sollte folgender Code die Datei erfolgreich in Sql speichern

    Visual Basic-Quellcode

    1. Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    2. ' Verbindungszeichenfolge zur SQL Server-Datenbank angeben
    3. Dim connectionString As String = SqlCommand_Connect_PriMa_Dokumente
    4. ' Dateipfad angeben
    5. Dim filePath As String = "C:\Temp\Test.pdf"
    6. ' Den Dateinamen extrahieren
    7. Dim fileName As String = Path.GetFileName(filePath)
    8. MsgBox(fileName)
    9. Dim fileExtension As String = Path.GetExtension(fileName)
    10. MsgBox(fileExtension)
    11. 'Dim ext As String = Path.GetExtension(filename) ' getting the file extension of the uploaded file
    12. ' Bytes aus der Datei lesen
    13. Dim fileBytes As Byte() = IO.File.ReadAllBytes(filePath)
    14. ' SQL-Befehl zum Einfügen des Dateiinhalts
    15. Dim insertQuery As String = "INSERT INTO sql_tbl_dokumente_2024 (sql_tbl_dokumente_name, sql_tbl_dokumente_erweiterung, sql_tbl_dokumente_inhalt) VALUES (@FileName, @FileExtension, @FileContent)"
    16. ' Verbindung zur Datenbank herstellen und Befehl ausführen
    17. Using connection As New SqlConnection(connectionString)
    18. Using command As New SqlCommand(insertQuery, connection)
    19. ' Parameter hinzufügen
    20. command.Parameters.AddWithValue("@FileName", fileName)
    21. command.Parameters.AddWithValue("@FileExtension", fileExtension)
    22. command.Parameters.AddWithValue("@FileContent", fileBytes)
    23. ' Verbindung öffnen
    24. connection.Open()
    25. ' Befehl ausführen
    26. command.ExecuteNonQuery()
    27. ' Verbindung schließen
    28. connection.Close()
    29. End Using
    30. End Using
    31. MsgBox("Die Datei wurde erfolgreich in der Datenbank gespeichert.")
    32. End Sub


    Die Datei wurde im Sql abgelegt, die Größe stimmt, die Richtigkeit ist noch nicht bewiesen

    So nun das auslesen der Datei aus den Sql:

    Visual Basic-Quellcode

    1. rivate Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    2. TABELLE_Test = New DataTable
    3. Dim con As New SqlConnection(SqlCommand_Connect_PriMa_Dokumente)
    4. Dim sqlcmd As String = "SELECT " &
    5. "sql_tbl_dokumente_id, " &
    6. "sql_tbl_dokumente_name, " &
    7. "sql_tbl_dokumente_erweiterung, " &
    8. "sql_tbl_dokumente_inhalt " &
    9. "FROM " &
    10. "sql_tbl_dokumente_2024 " &
    11. "WHERE " &
    12. "sql_tbl_dokumente_id ='4' "
    13. Dim DataAdapter As New SqlDataAdapter(sqlcmd, con)
    14. Try
    15. con.Open()
    16. DataAdapter.Fill(TABELLE_Test)
    17. con.Close()
    18. 'MsgBox(TABELLE_Test)
    19. Catch ex As Exception
    20. MsgBox("Fehlermeldung!" & vbCrLf & "SQL-Server FehlerBenutzer" & " " & ex.ToString, MsgBoxStyle.Exclamation)
    21. End
    22. Finally
    23. End Try
    24. Dim bytes As Byte()
    25. bytes = System.Text.Encoding.Unicode.GetBytes(TABELLE_Test.Rows(0).Item("sql_tbl_dokumente_inhalt").ToString)
    26. IO.File.WriteAllBytes("C:/Temp/Test3.pdf", bytes)
    27. End Sub


    Die Datei wurde in C: \Temp geschrieben, ist immer 1 Byte zu gross und leider gemäß Reader fehlerhaft.

    Mein Bauch sagt ganz fest das der System.Text.Encoding.Unicode.GetBytes(TABELLE_Test.Rows(0).Item("sql_tbl_dokumente_inhalt").ToString) um 1 Byte gekürzt werden muss

    Wäre euch um einen freundschaftlichen Schubs in die richtige Richtung sehr dankbar.

    Besten Dank

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

    Ich finde so Einzeilerkommentare total irritierend, und in diesem Fall steht in den meisten nur die deutsche Übersetzung des Namens der Methode, die du nutzt.

    Ein DataAdapter öffnet und schließt seine Verbindung selbst.

    Dein eigentliches Problem besteht aus einem Rattenschwanz an falschem Umgang mit den Datentypen würde ich sagen. Der Dokumenteninhalt wird in deinem Button2 eigentlich ganz säuberlich als Bytearray in die Datenbank gedrückt.
    Was du rausholst sind leider nur Objects, weil die DataTable son olles untypisiertes Dingen is. Aber vermutlich sind dadrin die Daten noch richtig.
    Allerdings gibts du das per .ToString aus und was da rauskommt, ist vermutlich ganz was anderes als was du denkst. Pack das mal in eine Variable und setz nen Haltepunkt und guck mal rein.
    Dim looki = TABELLE_Test.Rows(0).Item("sql_tbl_dokumente_inhalt").ToString
    Aber was auch immer man sich da wünschen könnte was da rauskommen soll, es kann nicht richtig sein, denn du hast ja keinen String in der DB abgespeichert, sondern ein Byte().

    Das beste wäre du verwendest eine typisierte DataTable, die kannst du dir im DataSet-Designer basteln und da gibt es explizit eben den Datentyp Byte(), den man für eine Spalte angeben kann.
    Auf Projekt Rechtsklick->Hinzufügen-> iwas anwählen z.B. Komponente dann aber in der nächsten Auswahl DataSet anwählen
    Deine Tabelle erstellen, und dann noch das DataSet auf dein Form ziehen. Hat man sich da einmal dran gewöhnt ist lesen aus ner DB genauso automatisch wie schreiben (bzw. wäre schreiben damit noch einfacher zu realisieren).

    Und dann isses ganz einfach mit
    File.WriteAllBytes(DeinPfad, DeinDataSet.DeineTabelle(zeilennummer).DeineBytearraySpalte)

    Alternativ kannst du auch mal versuchen dein Object korrekt zu casten.
    Dim bytes = DirectCast(TABELLE_Test.Rows(0).Item("sql_tbl_dokumente_inhalt"), Byte())

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