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:
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.
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.
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.
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.