简体   繁体   中英

Vb.NET MS Access SQL UPDATE Syntax Issue

I have been hammering away at this for hours but haven't gotten it right so I decided to post.

My Vb.NET app has a 2 Jpgs on the harddrive. One is LowRes and the other is HighRes . I want to save both pictures in the same record in a Microsoft Access 2007 database via INSERT , which works fine, and then UPDATE to add the second one. The UPDATE is not working.

I pieced together a bunch of code I found online for the INSERT code (learning as I go) and eventually figured something out that actually worked. However, trying to tweak the function to do a UPDATE to add the second picture is proving difficult. I suspect its something to do with me specifying parameters wrong?

The database has 1 table Records with 3 columns RecordID (which is Text, and a autonumber primary key which is pulled from Form1.Tb_RecordID.Text ), HighRes (which is OLE) and LowRes (Which is also OLE). The database is named Database.accdb .

I call the subroutine with:

Save_To_Database("LowProfile.jpg", "LowRes")

if I want it to INSERT an OLE image in the "LowRes" column. I then call

Update_To_Database("HighProfile.jpg", "HighRes")

to update the record with the HighRes picture. I eventually want to consolidate these functions one to one and use ByVals to determine if it should Update or Insert.

This works fine:

Sub Save_To_Database(ByVal Filename As String, ByVal Res As String)

    Dim cnString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=Database.accdb"
    Dim theQuery As String = "INSERT INTO Records([RecordID],[" & Res & "]) values (" & Form1.Tb_RecordID.Text & ", @Img)"

    Try
        Dim fs As FileStream
        fs = New FileStream(Filename, FileMode.Open, FileAccess.Read)
        Dim picByte As Byte() = New Byte(fs.Length - 1) {}
        fs.Read(picByte, 0, System.Convert.ToInt32(fs.Length))
        fs.Close()
        Dim CN As New OleDbConnection(cnString)
        CN.Open()
        Dim imgParam As New OleDbParameter()
        imgParam.OleDbType = OleDbType.Binary
        imgParam.ParameterName = "Img"
        imgParam.Value = picByte
        Dim cmd As New OleDbCommand(theQuery, CN)
        cmd.Parameters.Add(imgParam)
        cmd.ExecuteNonQuery()
        MessageBox.Show("Image successfully saved.")
        cmd.Dispose()
        CN.Close()
        CN.Dispose()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub

However, my UPDATE code fails with a syntax error on the SQL statement:

Sub Update_To_Database(ByVal Filename As String, ByVal Res As String)

    Dim cnString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=Database.accdb"
    Dim theQuery As String = "UPDATE Records SET ([" & Res & "]) values (@Img) WHERE RecordID =" & Form1.Tb_RecordID.Text

    MsgBox(theQuery)

    Try
        Dim fs As FileStream
        fs = New FileStream(Filename, FileMode.Open, FileAccess.Read)
        Dim picByte As Byte() = New Byte(fs.Length - 1) {}
        fs.Read(picByte, 0, System.Convert.ToInt32(fs.Length))
        fs.Close()
        Dim CN As New OleDbConnection(cnString)
        CN.Open()
        Dim imgParam As New OleDbParameter()
        imgParam.OleDbType = OleDbType.Binary
        imgParam.ParameterName = "Img"
        imgParam.Value = picByte
        Dim cmd As New OleDbCommand(theQuery, CN)
        cmd.Parameters.Add(imgParam)
        cmd.ExecuteNonQuery()
        MessageBox.Show("Image successfully saved.")
        cmd.Dispose()
        CN.Close()
        CN.Dispose()
    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub

Anyone see the problem? Or a way to improve the code?

Your original problem is the fact that you tried to write an update statement using the syntax of an insert statement. An easy fix would be simply to change the update statement to the correct syntax.

However, there are a number of things in your code that could be and should be changed, so I wrote an example based on your code that still can be improved further:

Sub Save_To_Database(ByVal Filename As String, ByVal RecordId As String, ByVal IsHighResolution As Boolean, ByVal IsNew As Boolean)

    Dim theQuery As String
    Dim cnString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;Data Source=Database.accdb"

    If IsNew Then
        theQuery = "INSERT INTO Records([RecordID],[" & IIf(IsHighResolution, "HighRes", "LowRes") & "]) values (@RecordId, @Img)"
    Else
        theQuery = "UPDATE Records SET " & IIf(IsHighResolution, "HighRes", "LowRes") & " = @Img WHERE RecordID = @RecordId"
    End If

    Try
        Using fs As New FileStream(Filename, FileMode.Open, FileAccess.Read)
            Dim picByte As Byte() = New Byte(fs.Length - 1) {}
            fs.Read(picByte, 0, System.Convert.ToInt32(fs.Length))
            Using CN As New OleDbConnection(ConnectionString)

                Dim cmd As New OleDbCommand(theQuery, CN)
                cmd.Parameters.Add("Img", OleDbType.Binary).Value = picByte
                cmd.Parameters.Add("@RecordId", OleDbType.Integer).Value = RecordId

                CN.Open()
                cmd.ExecuteNonQuery()
                MessageBox.Show("Image successfully saved.")
            End Using
        End Using

    Catch ex As Exception
        MessageBox.Show(ex.Message)
    End Try

End Sub

Points of interest:

  1. Insert and update is now handled by the same method, only difference is a Boolean parameter that specifies if this is a new record or an existing one.

  2. Queries are now safe from sql injection. The only concatenation here is the column name that you can't parameterize in sql, but it is decided inside the sub itself. When you use the sub, you only pass a boolean value indicating of this is a high resolution image.

  3. The Using block is recommended to use whenever you are using anything that implements the IDisposable interface. This ensures the correct closer and disposal even in a case of an exception being thrown.

  4. Parameters code simplified.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM