使用ADO将原始文件数据插入到Access表的BLOB(“OLE Object”)字段中 [英] Insert raw file data into BLOB ("OLE Object") field of Access table using ADO
问题描述
我试图插入一个文件到MS Access数据库,到 OLE对象
类型的字段。我使用 C ++
和 ADO
。
目前我收到错误 无效的指针错误
。
我认为我的问题是错误的变体,因为这是我第一次使用它们。我从此代码示例中学习,但是有解决如何从磁盘插入文件到 variant
有问题。
他们从数据库读取,并将其复制到新记录中,因此我从磁盘读取文件,然后将其插入变体的部分缺失。
当我选择菜单项时,我在GUI中激活我的代码。数据库有一个名为 test
的表,其中的字段 ID
是主键和字段
这是 OLE对象
类型。
在线搜索后,我发现没有什么可以帮助我
以下是说明问题的最小代码段(错误检查极少):
wchar_t * bstrConnect = LProvider = Microsoft.ACE.OLEDB.12.0; \
数据源= C:\\Users\\Smiljkovic85\\Desktop\\ \\\OLE.accdb;
try
{
HRESULT hr = CoInitialize(NULL);
//连接
ADODB :: _ ConnectionPtr pConn(LADODB.Connection);
// recordset
ADODB :: _ RecordsetPtr pRS(LADODB.Recordset);
//连接到DB
hr = pConn->打开(bstrConnect,Ladmin,L,ADODB :: adConnectUnspecified);
//打开文件
std :: ifstream(LC:\\Users\\Smiljkovic85\\Desktop\\file.pdf,
std :: ios :: ate | std :: ios :: binary);
//获取文件大小
int fileSize = in.tellg();
//这里我尝试修改上面链接的示例代码
pRS-> Open(Ltest,_variant_t((IDispatch *)pConn,true),
ADODB :: adOpenKeyset,ADODB :: adLockOptimistic,ADODB :: adCmdTable);
//添加新记录
pRS-> AddNew();
//复制粘贴
_variant_t varChunk;
SAFEARRAY FAR * psa;
SAFEARRAYBOUND rgsabound [1];
rgsabound [0] .lLbound = 0;
//修改为我们的文件大小
rgsabound [0] .cElements = fileSize;
psa = SafeArrayCreate(VT_UI1,1,rgsabound);
// ===================尝试将文件添加到变量
char * chData =(char *)psa-> ; pvData;
chData = new char [fileSize];
in.read(chData,fileSize);
/ * =============我甚至尝试了以下操作:
char * chData = new char [fileSize];
in.read(chData,fileSize);
BYTE * pData;
SafeArrayAccessData(psa,(void **)& pData);
memcpy(pData,chData,fileSize);
SafeArrayUnaccessData(psa);
=============== * /
// =============== ================================
//将Safe数组分配给变体。
varChunk.vt = VT_ARRAY | VT_UI1;
varChunk.parray = psa;
pRS-> Fields-> GetItem(Lfield) - > AppendChunk(varChunk);
//将此记录添加到DB
pRS-> Update();
//清除
delete [] chData;
in.close();
pRS->关闭();
pConn-> Close();
CoUninitialize();
}
catch(_com_error e)
{
MessageBox(hWnd,(LPWSTR)e.Description(),L,0);
}
您能帮我修改这段代码, ?
编辑:
我在这里搜索帮助和两个帖子给了我一个想法。仍然没有我的解决方案工作。
我现在得到的是以下错误:当微软发生问题时访问正在与MS Access中的ole服务器或activex控制
进行通信。我已经在线搜索解决方案,但没有运气,每个链接声称它与访问,而不是与代码。
请帮助...
由于您已经使用 ADODB.Connection
和 ADODB .Recordset
对象,您应该能够使用二进制 ADODB.Stream
对象来操作文件内容
-
.LoadFromFile
以填充Stream的文件内容, -
.Read
将其从Stream中拉回并将其存储在数据库字段中。
很遗憾,我无法提供C ++示例,但在VBA中,代码如下:
Dim con As ADODB.Connection,rst As ADODB.Recordset,strm As ADODB.Stream
Set con = New ADODB.Connection
con.Open _
Provider = Microsoft.ACE.OLEDB.12.0; & _
Data Source = C:\Users\Public\Database1.accdb
设置rst =新ADODB.Recordset
rst.Opentest,con,adOpenKeyset,adLockOptimistic ,adCmdTable
设置strm =新ADODB.Stream
strm.Type = adTypeBinary
strm.Open
strm.LoadFromFileC:\Users\Gord\Desktop\ test.pdf
rst.AddNew
strm.Position = 0
rst.Fields(FileData)。Value = strm.Read
rst.Update
rst .Close
Set rst = Nothing
con.Close
设置con = Nothing
strm.Close
设置strm = Nothing
I am trying to insert a file into MS Access database, into a field of OLE Object
type. I am using C++
and ADO
.
Currently I get error Invalid pointer error
.
I think that my problem is mishandling variants since this is the first time I use them. I am learning from this code example but have problem understanding how to insert file from disk into variant
.
They read it from database, and copied it into new record so the part where I read file from disk and then insert it into variant is missing.
I am firing off my code in GUI when menu item is selected. Database has one table named test
with fields ID
which is primary key and field
which is of OLE Object
type.
After searching online I have found nothing that can help me.
Here is smallest code snippet possible that illustrates the problem ( error checking is minimal):
wchar_t *bstrConnect = L"Provider=Microsoft.ACE.OLEDB.12.0; \
Data Source = C:\\Users\\Smiljkovic85\\Desktop\\OLE.accdb";
try
{
HRESULT hr = CoInitialize(NULL);
// connection
ADODB::_ConnectionPtr pConn(L"ADODB.Connection");
// recordset
ADODB::_RecordsetPtr pRS(L"ADODB.Recordset");
// connect to DB
hr = pConn->Open(bstrConnect, L"admin", L"", ADODB::adConnectUnspecified);
// open file
std::ifstream in(L"C:\\Users\\Smiljkovic85\\Desktop\\file.pdf",
std::ios::ate | std::ios::binary);
// get file size
int fileSize = in.tellg();
// here I tried to adapt code from the example linked above
pRS->Open(L"test", _variant_t((IDispatch*)pConn, true),
ADODB::adOpenKeyset, ADODB::adLockOptimistic, ADODB::adCmdTable);
// add new record
pRS->AddNew();
// copy pasted
_variant_t varChunk;
SAFEARRAY FAR *psa;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
// modify to our file size
rgsabound[0].cElements = fileSize;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
//=================== try to add file into variant
char *chData = (char *)psa->pvData;
chData = new char[fileSize];
in.read(chData, fileSize);
/* ============= I have even tried the following :
char *chData = new char[fileSize];
in.read(chData, fileSize);
BYTE* pData;
SafeArrayAccessData(psa, (void **)&pData);
memcpy(pData, chData, fileSize);
SafeArrayUnaccessData(psa);
===============*/
//=================================================
// Assign the Safe array to a variant.
varChunk.vt = VT_ARRAY | VT_UI1;
varChunk.parray = psa;
pRS->Fields->GetItem(L"field")->AppendChunk(varChunk);
// add this record into DB
pRS->Update();
// cleanup
delete[] chData;
in.close();
pRS->Close();
pConn->Close();
CoUninitialize();
}
catch (_com_error e)
{
MessageBox(hWnd, (LPWSTR)e.Description(), L"", 0);
}
Can you help me to modify this code snippet so I can insert file into variant?
EDIT:
I have searched here for help and two posts that gave me an idea. Still none of my solutions work. You can see them in the above code snippet, in the comments.
What I get now, is the following error: a problem occurred while microsoft access was communicating with the ole server or activex control
in MS Access. I have searched online for solution but had no luck, every link claims it has to do with access and not with the code.
Please help...
Since you are already using ADODB.Connection
and ADODB.Recordset
objects you should be able to use a binary ADODB.Stream
object to manipulate the file contents with
.LoadFromFile
to fill the Stream with the file contents, and.Read
to pull it back out of the Stream and store it in the database field.
Unfortunately I cannot offer a C++ example, but in VBA the code would be:
Dim con As ADODB.Connection, rst As ADODB.Recordset, strm As ADODB.Stream
Set con = New ADODB.Connection
con.Open _
"Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Users\Public\Database1.accdb"
Set rst = New ADODB.Recordset
rst.Open "test", con, adOpenKeyset, adLockOptimistic, adCmdTable
Set strm = New ADODB.Stream
strm.Type = adTypeBinary
strm.Open
strm.LoadFromFile "C:\Users\Gord\Desktop\test.pdf"
rst.AddNew
strm.Position = 0
rst.Fields("FileData").Value = strm.Read
rst.Update
rst.Close
Set rst = Nothing
con.Close
Set con = Nothing
strm.Close
Set strm = Nothing
这篇关于使用ADO将原始文件数据插入到Access表的BLOB(“OLE Object”)字段中的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!