将图像存储到Access数据库的附件字段中

我正在写一个VB应用程序,我需要在数据库中存储图像。 用户select他们的计算机上的图像,这给了我一个string的path。 这里是我的尝试,但是我得到的错误“一个INSERT INTO查询不能包含多值字段。

这是我的代码:

Dim buff As Byte() = Nothing Public Function ReadByteArrayFromFile(ByVal fileName As String) As Byte() Dim fs As New FileStream(fileName, FileMode.Open, FileAccess.Read) Dim br As New BinaryReader(fs) Dim numBytes As Long = New FileInfo(fileName).Length buff = br.ReadBytes(CInt(numBytes)) Return buff End Function Sub .... Dim connImg As New OleDbConnection Dim sConnString As String Dim cmdImg As New OleDbCommand sConnString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & My.Settings.DB & ";Persist Security Info=False;" connImg = New OleDbConnection(sConnString) connImg.Open() cmdImg.Connection = connImg cmdImg.CommandType = CommandType.Text If d.slogo <> "" Then cmdImg.CommandText = "INSERT INTO Logo ( refId, [type], [img] ) VALUES(@refId, @type, @imgBinary)" cmdImg.Parameters.Add("@refId", OleDbType.Double).Value = refId cmdImg.Parameters.Add("@type", OleDbType.Double).Value = 0 cmdImg.Parameters.Add("@imgBinary", OleDbType.VarBinary).Value = ReadByteArrayFromFile(PathToImage) cmdImg.ExecuteNonQuery() End If .... End Sub 

我试过在网上search其他解决scheme,但似乎我find的是VB6或VBA代码。 而且我知道人们会争辩说,图像不应该存储在数据库中,但在这种情况下,这是我唯一的select。

感谢您的任何帮助!

正如您已经发现的那样,您不能使用SQL语句将文件插入到Access数据库的“ Attachment字段中。 您必须使用ACE DAO Field2对象的LoadFromFile()方法。 以下C#代码适用于我。 它是从这里的Office博客条目改编的。

 using System; using System.Collections.Generic; using System.Linq; using System.Text; using Microsoft.Office.Interop.Access.Dao; namespace daoConsoleApp { class Program { static void Main(string[] args) { // This code requires the following COM reference in your project: // // Microsoft Office 14.0 Access Database Engine Object Library // var dbe = new DBEngine(); Database db = dbe.OpenDatabase(@"C:\__tmp\testData.accdb"); try { Recordset rstMain = db.OpenRecordset( "SELECT refId, img FROM Logo WHERE refId = 1", RecordsetTypeEnum.dbOpenDynaset); if (rstMain.EOF) { // record does not already exist in [Logo] table, so add it rstMain.AddNew(); rstMain.Fields["refId"].Value = 1; } else { rstMain.Edit(); } // retrieve Recordset2 object for (potentially multi-valued) [img] field // of the current record in rstMain Recordset2 rstAttach = rstMain.Fields["img"].Value; rstAttach.AddNew(); Field2 fldAttach = (Field2)rstAttach.Fields["FileData"]; fldAttach.LoadFromFile(@"C:\__tmp\testImage.jpg"); rstAttach.Update(); rstAttach.Close(); rstMain.Update(); rstMain.Close(); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } } } 

我做了基于上述代码和从这里的博客条目相同的东西。

这是我的vb.net代码,它允许我做一个OpenFileDialog和多个select,该function将处理存储多个文件就好了。 虽然我不得不添加一个引用到我的项目的Microsoft Office 15.0 Access数据库引擎对象库,使其正常工作。 我想你可以下降到12.0或14.0。

 Private Sub AddAttachment(ByVal Files() As String) Const Caller = "AddAttachment" Dim dbe = New Microsoft.Office.Interop.Access.Dao.DBEngine() Dim db As Microsoft.Office.Interop.Access.Dao.Database db = dbe.OpenDatabase(dbPath) Try Dim rstMain As Microsoft.Office.Interop.Access.Dao.Recordset rstMain = db.OpenRecordset("SELECT ID, fieldName FROM tableName WHERE ID = " + (dt.Rows(currentRow).Item("ID").ToString), Microsoft.Office.Interop.Access.Dao.RecordsetTypeEnum.dbOpenDynaset) If (rstMain.EOF) Then rstMain.AddNew() rstMain.Fields("ID").Value = 1 Else For Each value As String In Files rstMain.Edit() Dim rstAttach As Microsoft.Office.Interop.Access.Dao.Recordset2 rstAttach = rstMain.Fields("ATTACHMENTS").Value rstAttach.AddNew() Dim fldAttach As Microsoft.Office.Interop.Access.Dao.Field2 fldAttach = rstAttach.Fields("FileData") fldAttach.LoadFromFile(value) rstAttach.Update() rstAttach.Close() Next rstMain.Update() rstMain.Close() End If Catch ex As Exception If Err.Number <> 3820 Then MsgBox(ex.Message) Else MsgBox("File of same name already attached", MsgBoxStyle.Critical, "Cannot attach file" & Caller) MessageBox.Show(ex.Message) End If End Try End Sub 

我现在正在处理RemoveAttachments的function,并保存附件字段中的文件。 我稍后会在这里发表。

还有一件事要补充。 如果你的数据库是encryption的,那么你将需要添加到OpenDatabase命令。

这是我在C#中使用的代码,但VB.NET代码将非常类似。 db = dbe.OpenDatabase(dbPath,false,false,“MS Access; PWD = password”);

我花了很多时间去尝试跟踪这个问题,我将尝试分解这个方法的各个部分。 MSDN文章可以在这里find。

第一个参数:dbPath,这与原始文章中的用法相同。 您要打开的数据库的位置和文件名。

第二个参数:错误。 这是一个真/假的说法,如果真的在独占模式打开数据库。 所以只有这个单一的程序可以使用它。 大多数情况下,这应该是错误的。 只有使用独家模式,如果你必须。

第三个参数:错误。 这是另一个真实/错误的论点。 这一次,如果它是真的,那么它将以只读模式打开数据库。这意味着你只能使用logging集来读取信息,而不能使用编辑,添加或删除方法。 根据您的需求,这可能是真的或假的。

第四个参数:这设置了如何打开数据库的特定属性。 在这种情况下。 它说,将Microsoft Access属性“PWD”设置为“密码”。 在这个属性设置将告诉方法使用密码“密码”打开一个encryption的数据库。 当然,你需要将“密码”更改为数据库的实际密码,但是我一直在寻找这个密码。

我希望这有帮助。