Home > Net >  Unable to save pdf file into access database
Unable to save pdf file into access database

Time:10-14

I'm trying to update an existing record in the access db table and save a pdf file. However, I'm getting "No value given for one or more parameters" error.

Please see the code below. Any help will be much appreciated.

Thanks

Dim strsql As String
Dim settings As String = ConfigurationManager.ConnectionStrings("ABCBO.My.MySettings.db_abcdealsConnectionString").ConnectionString
Dim con As New OleDbConnection
Private Sub printtopdf_Click(sender As Object, e As EventArgs) Handles printtopdf.Click
    con.ConnectionString = settings
    Try
        Dim fs As New FileStream("E:\NewApp\test1.pdf", FileMode.Open, FileAccess.Read)
        strsql = "UPDATE ABC_DEALS SET CONFIRMATION_COPY = @AT1 WHERE DEAL_TICKET = '" & TextBox5.Text & "'"
        Dim cmd As New OleDbCommand(strsql, con)
        Dim byteArr(CInt(fs.Length)) As Byte
        fs.Read(byteArr, 0, fs.Length)
        fs.Close()
        con.Open()
        cmd.Parameters.Add("@AT1", OleDbType.Binary).Value = byteArr
        cmd.ExecuteNonQuery()
        con.Close()
    Catch exc As Exception
        MsgBox(exc.Message)
        con.Close()
    End Try
End Sub

CodePudding user response:

FileStream, OleDbConnection, and OleDbCommand all have a Dispose method that needs to be called so unmanaged resources can be released. Vb.net provides Using...End Using blocks that will handle this for us and also close the connection and the stream. The Using block in the data access code includes both the connection and the command. Note the comma after the connection line.

You are trying to do too many things in the click method. Separate the data access code from the rest.

Always use parameters. User input like TextBox5.Text could introduce malicious code into your database. Parameter values are not considered executable code by the database.

Pass the connection string to the constructor of the connection.

Pass the CommandText and the Connection to the constructor of the command.

Don't open the connection until directly before the Execute...

Even if this doesn't solve the problem, it will offer you a clearer idea of where the problem is. Put in a break point and step through the code checking for variable values.

Private settings As String = ConfigurationManager.ConnectionStrings("ABCBO.My.MySettings.db_abcdealsConnectionString").ConnectionString

Private Sub printtopdf_Click(sender As Object, e As EventArgs) Handles Button1.Click 'printtopdf.Click
    Dim byteArr As Byte()
    Dim path As String = "E:\NewApp\test1.pdf"
    Try
        Using fs As New FileStream(path, FileMode.Open, FileAccess.Read)
            ReDim byteArr(CInt(fs.Length))
            fs.Read(byteArr, 0, CInt(fs.Length))
        End Using
        Dim Updated = UpdateDatabase(byteArr, CInt(TextBox5.Text))
        MessageBox.Show($"{Updated} has been successfully updated.")
    Catch exc As Exception
        MsgBox(exc.Message)
    End Try
End Sub

Private Function UpdateDatabase(PDF As Byte(), Ticket As Integer) As Integer
    Dim strsql = "UPDATE ABC_DEALS SET CONFIRMATION_COPY = @AT1 WHERE DEAL_TICKET = @Ticket;"
    Dim RecordsUpdated As Integer
    Using con As New OleDbConnection(settings),
         cmd As New OleDbCommand(strsql, con)
        cmd.Parameters.Add("@AT1", OleDbType.Binary).Value = PDF
        cmd.Parameters.Add("@Ticket", OleDbType.Integer).Value = Ticket
        con.Open()
        RecordsUpdated = cmd.ExecuteNonQuery()
    End Using
    Return RecordsUpdated
End Function

EDIT

Private Function GetByteArrayFromFile(FilePath As String) As Byte()
    Dim file As Byte()
    Using stream As New FileStream(FilePath, FileMode.Open, FileAccess.Read),
            reader As New BinaryReader(stream)
        file = reader.ReadBytes(CInt(stream.Length))
    End Using
    Return file
End Function

Private Sub printtopdf_Click(sender As Object, e As EventArgs) Handles Button1.Click 'printtopdf.Click
    Dim path As String = "E:\NewApp\test1.pdf"
    Dim byteArr = GetByteArrayFromFile(path)
    Try
        Dim Updated = UpdateDatabase(byteArr, CInt(TextBox5.Text))
        MessageBox.Show($"{Updated} has been successfully updated.")
    Catch exc As Exception
        MsgBox(exc.Message)
    End Try
End Sub

EDIT 2

I see 3 places that the code needs to be changed to accomidate a Long. I have added a validation TryParse to the code to make sure the input is the correct type.

Old code 1

Dim Updated = UpdateDatabase(byteArr, CInt(TextBox5.Text))

New code 1

    Dim ticket As Long
    If Not Long.TryParse(TextBox5.Text, ticket) Then
        MessageBox.Show("Please enter a valid ticket number")
        Exit Sub
    End If
    Dim Updated = UpdateDatabase(byteArr, ticket)

Old code 2

Private Function UpdateDatabase(PDF As Byte(), Ticket As Integer) As Integer

New code 2 Note: The return type stays Integer.

Private Function UpdateDatabase(PDF As Byte(), Ticket As Long) As Integer

Old code 3

cmd.Parameters.Add("@Ticket", OleDbType.Integer).Value = Ticket

New code 3 It seems the the OleDbType.BigInt maps to Int64. In Access the field should be Number 8 bytes. Not positive of this. You may have to play with it a bit.

    cmd.Parameters.Add("@Ticket", OleDbType.BigInt).Value = Ticket
  • Related