无法将pdf文件保存到access数据库
Unable to save pdf file into access database
我正在尝试更新访问数据库中的现有记录 table 并保存一个 pdf 文件。
但是,我收到“没有为一个或多个参数指定值”错误。
请看下面的代码。任何帮助将不胜感激。
谢谢
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
FileStream
、OleDbConnection
和 OleDbCommand
都有一个需要调用的 Dispose
方法,以便释放非托管资源。 Vb.net 提供 Using...End Using
块来为我们处理这个问题并关闭连接和流。数据访问代码中的 Using
块包括连接和命令。注意连接线后的逗号。
您试图在点击方法中做太多事情。将数据访问代码与其余部分分开。
总是使用参数。 TextBox5.Text
等用户输入可能会将恶意代码引入您的数据库。参数值不被数据库视为可执行代码。
将连接字符串传递给连接的构造函数。
将 CommandText
和 Connection
传递给命令的构造函数。
在 Execute...
之前不要打开连接
即使这不能解决问题,它也会让您更清楚地了解问题出在哪里。放置一个断点并逐步执行代码检查变量值。
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
编辑
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
编辑 2
我看到 3 个地方需要更改代码以适应 Long。我在代码中添加了验证 TryParse
以确保输入的类型正确。
旧代码 1
Dim Updated = UpdateDatabase(byteArr, CInt(TextBox5.Text))
新代码 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)
旧代码 2
Private Function UpdateDatabase(PDF As Byte(), Ticket As Integer) As Integer
新代码 2 注意:return 类型保持整数。
Private Function UpdateDatabase(PDF As Byte(), Ticket As Long) As Integer
旧代码 3
cmd.Parameters.Add("@Ticket", OleDbType.Integer).Value = Ticket
新代码 3 OleDbType.BigInt 似乎映射到 Int64。在 Access 中,该字段应为 Number 8 字节。对此并不乐观。你可能需要玩一下它。
cmd.Parameters.Add("@Ticket", OleDbType.BigInt).Value = Ticket
最后回顾
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
If String.IsNullOrEmpty(TextBox5.Text) Then
MessageBox.Show("Please enter a valid ticket number")
Exit Sub
End If
Dim Updated = UpdateDatabase(byteArr, TextBox5.Text)
MessageBox.Show($"{Updated} has been successfully updated.")
Catch exc As Exception
MsgBox(exc.Message)
End Try
End Sub
Private settings As String = ConfigurationManager.ConnectionStrings("ABCBO.My.MySettings.db_abcdealsConnectionString").ConnectionString
Private Function UpdateDatabase(PDF As Byte(), Ticket As String) 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.LongVarBinary).Value = PDF
cmd.Parameters.Add("@Ticket", OleDbType.VarChar).Value = Ticket
con.Open()
RecordsUpdated = cmd.ExecuteNonQuery()
End Using
Return RecordsUpdated
End Function
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
我正在尝试更新访问数据库中的现有记录 table 并保存一个 pdf 文件。 但是,我收到“没有为一个或多个参数指定值”错误。
请看下面的代码。任何帮助将不胜感激。
谢谢
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
FileStream
、OleDbConnection
和 OleDbCommand
都有一个需要调用的 Dispose
方法,以便释放非托管资源。 Vb.net 提供 Using...End Using
块来为我们处理这个问题并关闭连接和流。数据访问代码中的 Using
块包括连接和命令。注意连接线后的逗号。
您试图在点击方法中做太多事情。将数据访问代码与其余部分分开。
总是使用参数。 TextBox5.Text
等用户输入可能会将恶意代码引入您的数据库。参数值不被数据库视为可执行代码。
将连接字符串传递给连接的构造函数。
将 CommandText
和 Connection
传递给命令的构造函数。
在 Execute...
即使这不能解决问题,它也会让您更清楚地了解问题出在哪里。放置一个断点并逐步执行代码检查变量值。
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
编辑
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
编辑 2
我看到 3 个地方需要更改代码以适应 Long。我在代码中添加了验证 TryParse
以确保输入的类型正确。
旧代码 1
Dim Updated = UpdateDatabase(byteArr, CInt(TextBox5.Text))
新代码 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)
旧代码 2
Private Function UpdateDatabase(PDF As Byte(), Ticket As Integer) As Integer
新代码 2 注意:return 类型保持整数。
Private Function UpdateDatabase(PDF As Byte(), Ticket As Long) As Integer
旧代码 3
cmd.Parameters.Add("@Ticket", OleDbType.Integer).Value = Ticket
新代码 3 OleDbType.BigInt 似乎映射到 Int64。在 Access 中,该字段应为 Number 8 字节。对此并不乐观。你可能需要玩一下它。
cmd.Parameters.Add("@Ticket", OleDbType.BigInt).Value = Ticket
最后回顾
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
If String.IsNullOrEmpty(TextBox5.Text) Then
MessageBox.Show("Please enter a valid ticket number")
Exit Sub
End If
Dim Updated = UpdateDatabase(byteArr, TextBox5.Text)
MessageBox.Show($"{Updated} has been successfully updated.")
Catch exc As Exception
MsgBox(exc.Message)
End Try
End Sub
Private settings As String = ConfigurationManager.ConnectionStrings("ABCBO.My.MySettings.db_abcdealsConnectionString").ConnectionString
Private Function UpdateDatabase(PDF As Byte(), Ticket As String) 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.LongVarBinary).Value = PDF
cmd.Parameters.Add("@Ticket", OleDbType.VarChar).Value = Ticket
con.Open()
RecordsUpdated = cmd.ExecuteNonQuery()
End Using
Return RecordsUpdated
End Function
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