Вставьте данные необработанного файла в поле BLOB («Объект OLE») таблицы Access с помощью ADO

Я пытаюсь вставить файл в базу данных MS Access, в поле OLE Object тип. я использую C++ а также ADO,

В настоящее время я получаю ошибку Invalid pointer error,

Я думаю, что моя проблема в неправильном обращении с вариантами, так как я использую их впервые. Я учусь у этот пример кода но есть проблемы с пониманием, как вставить файл с диска в variant,

Они читают его из базы данных и копируют в новую запись, поэтому часть, где я читаю файл с диска, а затем вставляю его в вариант, отсутствует.

Я запускаю свой код в графическом интерфейсе, когда выбран пункт меню. База данных имеет одну таблицу с именем test с полями ID который является первичным ключом и field который из OLE Object тип.

После поиска в Интернете я не нашел ничего, что может мне помочь.

Вот наименьший возможный фрагмент кода, который иллюстрирует проблему (проверка ошибок минимальна):

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);
}

Можете ли вы помочь мне изменить этот фрагмент кода, чтобы я мог вставить файл в вариант?

РЕДАКТИРОВАТЬ:

Я искал здесь помощь и два сообщения, которые дали мне идею. Все еще ни одно из моих решений не работает. Вы можете увидеть их в приведенном выше фрагменте кода, в комментариях.

Теперь я получаю следующую ошибку: a problem occurred while microsoft access was communicating with the ole server or activex control в MS Access. Я искал в Интернете решение, но мне не повезло, каждая ссылка утверждает, что это связано с доступом, а не с кодом.

Пожалуйста помоги…

2

Решение

Поскольку вы уже используете ADODB.Connection а также ADODB.Recordset объекты, которые вы должны быть в состоянии использовать двоичный ADODB.Stream объект для управления содержимым файла с

  • .LoadFromFile заполнить поток содержимым файла, и
  • .Read вытащить его обратно из потока и сохранить в поле базы данных.

К сожалению, я не могу предложить пример 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"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
1

Другие решения


По вопросам рекламы [email protected]