處理原生應用程式的錯誤
若為使用 Microsoft Visual C++ for Devices 開發的應用程式,您可以從應用程式執行階段、資料提供者,或是透過使用 Microsoft SQL Server Compact 3.5 ActiveX 錯誤控制項物件與集合來取得錯誤資訊。使用 SQL Server Compact 3.5 錯誤控制項物件與集合是處理 Replication、RemoteDataAccess 及 Engine 物件錯誤的方法。
擷取錯誤資訊
以 MicrosoftVisual C++ for Devices 撰寫的應用程式可以從 SQL Server Compact 3.5 接收比 HRESULT 更詳細的資訊。要如何擷取此項擴充錯誤資訊,取決於應用程式以下列哪一種方法與 SQL Server Compact 3.5 互動:
OLE DB 錯誤物件
SQL Server Compact 3.5 的 OLE DB 提供者會傳回一組豐富的錯誤物件,可使用 OLE DB 錯誤物件加以存取。OLE DB 錯誤物件會儲存多層錯誤,並且提供超出標準錯誤的額外資訊。如需詳細資訊,請參閱<使用 OLE DB 錯誤物件 (SQL Server Compact)>。
SQL Server Compact 3.5 錯誤控制項物件與集合
Replication、RemoteDataAccess 及 Engine 物件會顯示可以透過 Visual C++ 存取的錯誤集合與參數。這些原生程式會參考 SQL Server 錯誤物件與集合,方式是將 sqlce_sync.hto 加入到專案參考,並且使用 include 指示詞來參考這些檔案。如需詳細資訊,請參閱<原始錯誤物件程式設計 (SQL Server Compact)>。
使用原生錯誤控制項物件和集合
SSCEErrors 集合對於每個產生的錯誤都含有一個 SSCEError 物件。每一個 SSCEError 物件都包含一個 SSCEParams 集合。您可以從 SSCEParams 集合的 SSCEParam 物件中擷取錯誤的描述。不同於 SQL Server,SQL Server Compact 3.5 會以六個參數的集合,傳回有關錯誤的詳細資訊。當您建立錯誤訊息時,請使用一系列的巢狀 FOR 迴圈,針對每一個 SSCEError 物件,來擷取其 SSCEParams 集合中的每一個 SSCEParam 物件。
範例
下列範例將說明如何使用裝置的 Visual C++ for Devices 來顯示 Replication、RemoteDataAccess 和 Engine 物件錯誤。
// 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;
}