AppendChunk et GetChunk, exemple de méthodes (VC++)
Cet exemple utilise les méthodes AppendChunk et GetChunk pour remplir un champ image avec des données d’un autre enregistrement.
// BeginAppendChunkCpp.cpp
// compile with: /EHsc /c
#import "msado15.dll" no_namespace rename("EOF", "EndOfFile")
#define ChunkSize 100
#include <ole2.h>
#include <stdio.h>
#include "conio.h"
#include "malloc.h"
#include "icrsint.h"
// extracts pubid, prinfo.
class CPubInfoRs : public CADORecordBinding {
BEGIN_ADO_BINDING(CPubInfoRs)
ADO_VARIABLE_LENGTH_ENTRY2(1, adVarChar, m_sz_pubid, sizeof(m_sz_pubid), l_pubid, TRUE)
ADO_VARIABLE_LENGTH_ENTRY2(3, adVarChar, m_sz_prinfo, sizeof(m_sz_prinfo), l_prinfo, TRUE)
END_ADO_BINDING()
public:
CHAR m_sz_pubid[10];
ULONG l_pubid;
CHAR m_sz_prinfo[200];
ULONG l_prinfo;
};
//Function declarations
inline void TESTHR(HRESULT x) { if FAILED(x) _com_issue_error(x); };
void AppendChunkX();
void PrintProviderError(_ConnectionPtr pConnection);
inline int myscanf(char* strDest, int n) {
char strExBuff[10];
char* pstrRet = fgets(strDest, n, stdin);
if (pstrRet == NULL)
return 0;
if (!strrchr(strDest, '\n'))
// Exhaust the input buffer.
do {
fgets(strExBuff, sizeof(strExBuff), stdin);
} while (!strrchr(strExBuff, '\n'));
else
// Replace '\n' with '\0'
strDest[strrchr(strDest, '\n') - strDest] = '\0';
return strlen(strDest);
}
inline char* mygets(char* strDest, int n) {
char strExBuff[10];
char* pstrRet = fgets(strDest, n, stdin);
if (pstrRet == NULL)
return NULL;
if (!strrchr(strDest, '\n'))
// Exhaust the input buffer.
do {
fgets(strExBuff, sizeof(strExBuff), stdin);
} while (!strrchr(strExBuff, '\n'));
else
// Replace '\n' with '\0'
strDest[strrchr(strDest, '\n') - strDest] = '\0';
return pstrRet;
}
int main() {
HRESULT hr = S_OK;
if (FAILED(::CoInitialize(NULL)))
return -1;
AppendChunkX();
::CoUninitialize();
}
void AppendChunkX() {
// Define ADO object pointers, initialize pointers on define. These are in the ADODB:: namespace.
_RecordsetPtr pRstPubInfo = NULL;
_ConnectionPtr pConnection = NULL;
char * token1;
// Define other variables
IADORecordBinding *picRs = NULL; // Interface Pointer declared.(VC++ Extensions)
CPubInfoRs pubrs; // C++ class object
HRESULT hr = S_OK;
_bstr_t strCnn("Provider='sqloledb'; Data Source='My_Data_Source'; Initial Catalog='pubs'; Integrated Security='SSPI';");
_bstr_t strMessage,strPubID,strPRInfo;
_variant_t varChunk;
long lngOffSet,lngLogoSize;
char pubId[50];
lngOffSet = 0;
UCHAR chData;
SAFEARRAY FAR *psa;
SAFEARRAYBOUND rgsabound[1];
rgsabound[0].lLbound = 0;
rgsabound[0].cElements = ChunkSize;
try {
// Open a Connection.
TESTHR(pConnection.CreateInstance(__uuidof(Connection)));
hr = pConnection->Open(strCnn, "", "", adConnectUnspecified);
TESTHR(hr= pRstPubInfo.CreateInstance(__uuidof(Recordset)));
pRstPubInfo->CursorType = adOpenKeyset;
pRstPubInfo->LockType = adLockOptimistic;
hr = pRstPubInfo->Open("pub_info", _variant_t((IDispatch*)pConnection,true),
adOpenKeyset, adLockOptimistic, adCmdTable);
// Open an IADORecordBinding interface pointer for Binding Recordset to a class
TESTHR(pRstPubInfo->QueryInterface(__uuidof(IADORecordBinding), (LPVOID*)&picRs));
// Bind the Recordset to a C++ Class here
TESTHR(picRs->BindToRecordset(&pubrs));
// Display the available logos here
strMessage = "Available logos are: " + (_bstr_t)"\n\n";
printf(strMessage);
int Counter = 0;
while (!(pRstPubInfo->EndOfFile)) {
printf("\n%s", pubrs.m_sz_pubid);
printf("\n%s", strtok_s(pubrs.m_sz_prinfo, ",", &token1));
// Display 5 records at a time and wait for user to continue..
if (++Counter >= 5) {
Counter = 0;
printf("\nPress any key to continue...");
_getch();
}
pRstPubInfo->MoveNext();
}
// Prompt For a Logo to Copy
printf("\nEnter the ID of a logo to copy: ");
myscanf(pubId, sizeof(pubId));
strPubID = pubId;
// Copy the logo to a variable in chunks
pRstPubInfo->Filter = "pub_id = '" + strPubID + "'";
lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;
// Create a safe array to store the array of BYTES
rgsabound[0].cElements = lngLogoSize;
psa = SafeArrayCreate(VT_UI1, 1, rgsabound);
long index1 = 0;
while (lngOffSet < lngLogoSize) {
varChunk = pRstPubInfo->Fields->Item["logo"]->GetChunk(ChunkSize);
// Copy the data only up to the Actual Size of Field.
for (long index = 0 ; index <= (ChunkSize - 1) ; index++) {
hr = SafeArrayGetElement(varChunk.parray, &index, &chData);
if (SUCCEEDED(hr)) {
// Take BYTE by BYTE and advance Memory Location
hr = SafeArrayPutElement(psa, &index1, &chData);
index1++;
}
else
break;
}
lngOffSet = lngOffSet + ChunkSize;
}
lngOffSet = 0;
printf("Enter a new Pub Id: ");
myscanf(pubrs.m_sz_pubid, sizeof(pubrs.m_sz_pubid));
strPubID = pubrs.m_sz_pubid;
printf("Enter descriptive text: " );
mygets(pubrs.m_sz_prinfo, sizeof(pubrs.m_sz_prinfo));
pRstPubInfo->AddNew();
pRstPubInfo->Fields->GetItem("pub_id")->PutValue(strPubID);
pRstPubInfo->Fields->GetItem("pr_info")->PutValue(pubrs.m_sz_prinfo);
// Assign the Safe array to a variant.
varChunk.vt = VT_ARRAY|VT_UI1;
varChunk.parray = psa;
hr = pRstPubInfo->Fields->GetItem("logo")->AppendChunk(varChunk);
// Update the table
pRstPubInfo->Update();
lngLogoSize = pRstPubInfo->Fields->Item["logo"]->ActualSize;
// Show the newly added record.
printf("New Record : %s\n Description : %s\n Logo Size : %s",
pubrs.m_sz_pubid,
pubrs.m_sz_prinfo,(LPCSTR)(_bstr_t)pRstPubInfo->Fields->
Item["logo"]->ActualSize);
// Delete new record because this is demonstration.
pConnection->Execute("DELETE FROM PUB_INFO WHERE pub_id = '"
+ strPubID +"'", NULL,adCmdText);
}
catch(_com_error &e) {
// Notify the user of errors if any.
_bstr_t bstrSource(e.Source());
_bstr_t bstrDescription(e.Description());
PrintProviderError(pConnection);
printf("Source : %s \n Description : %s\n", (LPCSTR)bstrSource,
(LPCSTR)bstrDescription);
}
// Clean up objects before exit.
if (pRstPubInfo)
if (pRstPubInfo->State == adStateOpen)
pRstPubInfo->Close();
if (pConnection)
if (pConnection->State == adStateOpen)
pConnection->Close();
}
void PrintProviderError(_ConnectionPtr pConnection) {
// Print Provider Errors from Connection object.
// pErr is a record object in the Connection's Error collection.
ErrorPtr pErr = NULL;
long nCount = 0;
long i = 0;
if ( (pConnection->Errors->Count) > 0) {
nCount = pConnection->Errors->Count;
// Collection ranges from 0 to nCount -1.
for (i = 0 ; i < nCount ; i++) {
pErr = pConnection->Errors->GetItem(i);
printf("\t Error number: %x\t%s", pErr->Number, (LPCSTR) pErr->Description);
}
}
}
Voir aussi
AppendChunk, méthode (ADO)
Field, objet
GetChunk, méthode (ADO)
Commentaires
https://aka.ms/ContentUserFeedback.
Prochainement : Tout au long de l'année 2024, nous supprimerons progressivement les GitHub Issues en tant que mécanisme de retour d'information pour le contenu et nous les remplacerons par un nouveau système de retour d'information. Pour plus d’informations, voir:Soumettre et afficher des commentaires pour