Gestion des erreurs dans les applications natives
Pour les applications que vous développez à l'aide de Microsoft Visual C++ for Devices, les informations sur les erreurs peuvent être obtenues au moment de l'exécution de l'application, auprès du fournisseur de données ou à l'aide des collections et des objets de contrôle d'erreur ActiveX Microsoft SQL Server Compact 3.5. Le recours aux collections et aux objets de contrôle d'erreur SQL Server Compact 3.5 permet de gérer les erreurs des objets Replication, RemoteDataAccess et Engine.
Extraction des informations sur les erreurs
Les applications écrites à l'aide de MicrosoftVisual C++ for Devices peuvent recevoir de SQL Server Compact 3.5 des informations bien plus détaillées que de simples valeurs HRESULT. La procédure d'extraction de ces informations complètes dépend de la méthode utilisée par l'application pour interagir avec SQL Server Compact 3.5. Ces méthodes sont les suivantes :
Objets erreur OLE DB
Le fournisseur OLE DB de SQL Server Compact 3.5 renvoie un jeu complet d'objets erreur, accessible par le biais d'objets erreur OLE DB. Les objets erreur OLE DB stockent plusieurs niveaux d'erreurs et fournissent des informations complémentaires, au-delà des erreurs standard. Pour plus d'informations, consultez Utilisation des objets d'erreur OLE DB (SQL Server Compact).
Collections et objets de contrôle d'erreur SQL Server Compact 3.5
Les objets Replication, RemoteDataAccess et Engine indiquent des paramètres et des collections d'erreurs accessibles via Visual C++ for Devices. Ces programmes natifs référencent les collections et objets erreur SQL Server en ajoutant sqlce_sync.hto aux références de projet et en référençant ces fichiers à l'aide de la directive include. Pour plus d'informations, consultez Programmation de l'objet erreur native (SQL Server Compact).
Utilisation des collections et des objets de contrôle d'erreur native
La collection SSCEErrors contient un objet SSCEError par erreur générée. Chaque objet SSCEError contient une collection SSCEParams. Les descriptions des erreurs peuvent être extraites des objets SSCEParam de la collection SSCEParams. À la différence de SQL Server, SQL Server Compact 3.5 renvoie des informations détaillées sur une erreur sous la forme d'une collection de six paramètres. Lorsque vous générez des messages d'erreur, utilisez une série de boucles FOR imbriquées pour extraire chaque objet SSCEParam de la collection SSCEParams pour chaque objet SSCEError.
Exemples
L'exemple suivant montre comment afficher les erreurs des objets Replication, RemoteDataAccess et Engine à l'aide de Visual C++ for Devices.
// Error handling example
#include "sqlce_sync.h"
void ShowErrors(ISSCEErrors* pISSCEErrors)
{
HRESULT hr;
LONG cbBuf;
LONG i;
LONG lErrorCount;
LONG lErrorIndex;
LONG lParamCount;
LONG lParamIndex;
VARIANT var;
VARIANT varParam;
WCHAR wszBuff[4096];
WCHAR* pwszBuffPos = &wszBuff[0];
BSTR bstr;
ISSCEError* pISSCEError = NULL;
ISSCEParams* pISSCEParams = NULL;
ISSCEParam* pISSCEParam = NULL;
BOOL fSuccess = FALSE;
// Initialize the variants.
VariantInit(&var);
VariantInit(&varParam);
// Get the count of errors.
if(FAILED(hr = pISSCEErrors->get_Count(&lErrorCount))) goto Exit;
if (lErrorCount <= 0)
{
MessageBox(NULL, L"No extended error information.",L"ShowErrors", MB_OK);
fSuccess = TRUE;
goto Exit;
}
// Display errors, one at a time, in a single message box.
// If there are too many errors, they might not all display correctly.
// If so, we recommend that you perform logic based on the number of errors.
for (lErrorIndex = 0; lErrorIndex < lErrorCount; lErrorIndex++)
{
cbBuf = swprintf(pwszBuffPos, L"E R R O R %d of %d\r\n",
lErrorIndex+1, lErrorCount);
pwszBuffPos += cbBuf;
// Get the next error record.
var.vt = VT_I4;
var.lVal = lErrorIndex;
if(FAILED(hr = pISSCEErrors->get_Item(var, &pISSCEError))) goto Exit;
// Error description
if (FAILED(hr = pISSCEError->get_Description(&bstr))) goto Exit;
cbBuf = swprintf(pwszBuffPos, L"DESCRIPTION: '%s'\r\n", bstr);
pwszBuffPos += cbBuf;
SysFreeString(bstr);
// Error number
if (FAILED(hr = pISSCEError->get_Number(&i))) goto Exit;
cbBuf = swprintf(pwszBuffPos, L"NUMBER: %8.8X\r\n", i);
pwszBuffPos += cbBuf;
// Native error
if (FAILED(hr = pISSCEError->get_NativeError(&i))) goto Exit;
cbBuf = swprintf(pwszBuffPos, L"NATIVE_ERROR: %d\r\n", i);
pwszBuffPos += cbBuf;
// Error source
if (FAILED(hr = pISSCEError->get_Source(&bstr))) goto Exit;
cbBuf = swprintf(pwszBuffPos, L"SOURCE: '%s'\r\n", bstr);
pwszBuffPos += cbBuf;
SysFreeString(bstr);
// Retrieve the error parameters.
if (FAILED(hr = pISSCEError->get_Params(&pISSCEParams))) goto Exit;
// Get the number of error parameters.
if (FAILED(hr = pISSCEParams->get_Count(&lParamCount))) goto Exit;
// Display the value of each parameter.
for (lParamIndex = 0; lParamIndex < lParamCount; lParamIndex++)
{
// Get the parameter object.
var.vt = VT_I4;
var.lVal = lParamIndex;
if (FAILED(hr = pISSCEParams->get_Item(var, &pISSCEParam))) goto Exit;
// Get and display the parameter value.
if (FAILED(hr = pISSCEParam->get_Param(&varParam))) goto Exit;
if (VT_I4 == varParam.vt || VT_UI4 == varParam.vt)
{
cbBuf = swprintf(pwszBuffPos, L"P%d: %d\r\n", lParamIndex,
(LONG) varParam.lVal);
}
else if (VT_I2 == varParam.vt || VT_UI2 == varParam.vt)
{
cbBuf = swprintf(pwszBuffPos, L"P%d: %d\r\n", lParamIndex,
(LONG) varParam.iVal);
}
else if (VT_BSTR == varParam.vt)
{
cbBuf = swprintf(pwszBuffPos, L"P%d: '%s'\r\n", lParamIndex,
varParam.bstrVal);
}
pwszBuffPos += cbBuf;
// Clear the variant.
VariantClear(&varParam);
// Release the parameter object.
pISSCEParam->Release();
pISSCEParam = NULL;
}
cbBuf = swprintf(pwszBuffPos, L"\r\n");
pwszBuffPos += cbBuf;
}
// Display the error information.
MessageBox(NULL, wszBuff,L"Error", MB_OK);
fSuccess = TRUE;
Exit:
// Release the parameter object.
if (pISSCEParam)
{
pISSCEParam->Release();
pISSCEParam = NULL;
}
// Release the parameters object.
if (pISSCEParams)
{
pISSCEParams->Release();
pISSCEParams = NULL;
}
// Release the error object.
if (pISSCEError)
{
pISSCEError->Release();
pISSCEError = NULL;
}
// The Errors object is released in calling routine.
if (!fSuccess)
{
MessageBox(NULL, L"Error while processing errors!",L"ShowErrors", MB_OK);
}
return;
}