我正在编写一个VB应用程序,我需要在数据库中存储图像。用户在他们的计算机上选择图像,这给了我作为字符串的路径。这是我的尝试,但是我收到错误“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
我尝试在线搜索其他解决方案,但似乎我发现的一切都是VB6或VBA代码。我知道人们会争辩说图像不应该存储在数据库中,但在这种情况下,它是我唯一的选择。
感谢您的帮助!
答案 0 :(得分:3)
正如您所发现的,您无法使用SQL语句将文件插入Access数据库中的Attachment
字段。您必须使用ACE DAO LoadFromFile()
对象的Field2
方法。以下C#代码适用于我。它改编自Office博客条目here。
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());
}
}
}
}
答案 1 :(得分:1)
我根据上面的代码和here的博客条目做了同样的事情。
这是我的vb.net代码,它允许我做一个OpenFileDialog和多个选择,该函数将处理存储多个文件就好了。虽然我必须添加对我的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的函数并从attachements字段保存文件。我稍后会在这里发布。
答案 2 :(得分:0)
要添加的另一件事。如果数据库已加密,则需要添加到OpenDatabase命令。
这是我在C#中使用的代码,但VB.NET代码非常相似。 db = dbe.OpenDatabase(dbPath,false,false,&#34; MS Access; PWD = password&#34;);
我花了很多时间尝试自己跟踪这个问题,我会尝试分解方法的各个部分。可以找到MSDN文章here。
第一个参数:dbPath,它与原始帖子中的用法相同。要打开的数据库的位置和文件名。
第二个论点:错误。这是一个true / false参数,如果为true,则以独占模式打开数据库。这样只有这个程序才能使用它。大多数时候这应该是假的。如果必须,只使用独占模式。
第三个论点:错误。这是另一个真/假的论点。这次如果它是真的那么它以只读模式打开数据库。这意味着你只能使用记录集来读取信息,而不能使用编辑,添加或删除方法。根据您的需要,这可能是真是假。
4th Argument:这将设置如何打开数据库的特定属性。在这种情况下。它说要设置Microsoft Access属性&#39; PWD&#39;密码&#39;。在此属性设置中将告诉使用密码&#39;密码&#39;打开加密数据库的方法。当然,您需要更改密码&#34;无论数据库的实际密码是打开的,但我已经打了一段时间。
我希望这会有所帮助。