Manipulando erros em aplicativos nativos
Para aplicativos desenvolvidos através do Microsoft Visual C++, as informações sobre erros podem ser obtidas a partir do tempo de execução do aplicativo, do provedor de dados ou com o uso das coleções e objetos de controle de erros do Microsoft SQL Server Compact 4.0 ActiveX. O uso das coleções e objetos de controle de erros do SQL Server Compact é o método para manipular erros dos objetos Engine.
Recuperando informações sobre erros
Os aplicativos criados com o MicrosoftVisual C++ recebem informações muito mais detalhadas do SQL Server Compact que os HRESULTs. O modo de recuperação dessas informações estendidas sobre erros depende de qual dos seguintes métodos o aplicativo usa para interagir com o SQL Server Compact:
Objetos de erro do OLE DB
O provedor OLE DB para SQL Server Compact retorna um sofisticado conjunto de objetos de erro que pode ser acessado usando objetos de erro do OLE DB. Os objetos de erro do OLE DB armazenam várias camadas de erros e fornecem informações adicionais, além dos erros padrão. Para obter mais informações, consulte Usando objetos de erro do OLE DB (SQL Server Compact).
Coleções e objetos de controle de erros do SQL Server Compact
Os objetos Engine revelam coleções e parâmetros de erros que podem ser acessados por meio do Visual C++. Esses programas nativos referenciam as coleções e objetos de erro do SQL Server adicionando sqlce_sync.hto às referências do projeto e referenciando esses arquivos usando a diretiva include. Para obter mais informações, consulte Programando o objeto de erro nativo (SQL Server Compact).
Usando as coleções e objetos de controle de erros nativos
A coleção SSCEErrors contém um objeto SSCEError para cada erro gerado. Cada objeto SSCEError contém uma coleção SSCEParams. As descrições dos erros podem ser recuperadas dos objetos SSCEParam da coleção SSCEParams. Diferentemente do SQL Server, o SQL Server Compact retorna informações detalhadas sobre um erro como uma coleção de seis parâmetros. Ao criar mensagens de erro, você deve usar uma série de loops FOR aninhados para recuperar cada objeto SSCEParam da coleção SSCEParams para cada objeto SSCEError.
Exemplos
O exemplo a seguir mostra como exibir os erros dos objetos Engine usando o Visual C++.
// 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;
}