在 OLE DB 中使用 Seek 方法

Seek 方法是客户端对 Microsoft SQL Server Compact 4.0 中的索引使用最广泛的方法。使用 Seek,您可以依据游标快速地查找行。

使用 Seek

为了使 Seek 方法能够正常工作,必须在搜索键中的列上定义索引。大多数查找操作都是针对特定的值,但也可以使用其他比较运算符(如“大于”或“小于”)进行查找。

IRowsetIndex::Seek 通过使用 OLE DB 中用于获取和设置数据的取值函数机制向访问接口传递值。相对于用于 IRowset::GetData 和 IRowset::SetData 的取值函数,用于 Seek方法的取值函数具有更多的限制。取值函数必须按照列出现在索引键中的顺序对其进行绑定。

只有可滚动游标支持 IRowsetPosition 接口。

示例

下面的示例说明了如何通过 OLE DB Provider for SQL Server Compact 4.0 对索引使用 IRowsetIndex::Seek。该示例仅包含与 Seek 方法有关的函数部分。

对于 32 位和 64 位平台,已更新下面的示例。64 位兼容类型来自 sqlce_oledb.h 本机头文件。可以在 %ProgramFiles%\Microsoft SQL Server Compact Edition\v3.5\Include 文件夹中找到 sqlce_oledb.h 本机头文件。有关详细信息,请参阅 Microsoft 网站上“OLE DB 编程人员指南”中的“OLE DB 64 位信息”主题。

TableID.eKind            = DBKIND_NAME;
TableID.uName.pwszName    = (WCHAR*)TABLE_EMPLOYEE;

IndexID.eKind            = DBKIND_NAME;
IndexID.uName.pwszName    = L"PK_Employees";

// Request ability to use IRowsetChange interface.
rowsetpropset[0].cProperties     = 1;
rowsetpropset[0].guidPropertySet = DBPROPSET_ROWSET;
rowsetpropset[0].rgProperties    = rowsetprop;

rowsetprop[0].dwPropertyID       = DBPROP_IRowsetIndex;
rowsetprop[0].dwOptions          = DBPROPOPTIONS_REQUIRED;
rowsetprop[0].colid              = DB_NULLID;
rowsetprop[0].vValue.vt          = VT_BOOL;
rowsetprop[0].vValue.boolVal     = VARIANT_TRUE;

// Open the table using the index.
hr = pIOpenRowset->OpenRowset(NULL, &TableID, &IndexID,
    IID_IRowsetIndex, sizeof(rowsetpropset)/sizeof(rowsetpropset[0]),
    rowsetpropset, (IUnknown**) &pIRowsetIndex);
if(FAILED(hr))
{
    goto Exit;
}

// Get the IRowset interface.
hr = pIRowsetIndex->QueryInterface(IID_IRowset, (void**) &pIRowset);
if(FAILED(hr))
{
    goto Exit;
}

///////////////////////////////////////////////////////////////////////
// Steps to get column data using IcolumnsInfo have been removed
///////////////////////////////////////////////////////////////////////

// Create a DBBINDING array.
dwBindingSize = sizeof(pwszEmployees)/sizeof(pwszEmployees[0]);
prgBinding = (DBBINDING*)CoTaskMemAlloc(sizeof(DBBINDING)*dwBindingSize);
if (NULL == prgBinding)
{
    hr = E_OUTOFMEMORY;
    goto Exit;
}

// Set initial offset for binding position.
dwOffset = 0;

// Prepare structures to create an accessor for each index.
for (dwIndex = 0; dwIndex < dwBindingSize; ++dwIndex)
{
    if (!GetColumnOrdinal(pDBColumnInfo, ulNumCols, pwszEmployees[dwIndex], &dwOrdinal))
    {
        hr = E_FAIL;
        goto Exit;
    }

    prgBinding[dwIndex].iOrdinal  = dwOrdinal;
    prgBinding[dwIndex].dwPart    = DBPART_VALUE | DBPART_STATUS | DBPART_LENGTH;
    prgBinding[dwIndex].obLength  = dwOffset;                                     
    prgBinding[dwIndex].obStatus  = prgBinding[dwIndex].obLength + sizeof(DBLENGTH);  
    prgBinding[dwIndex].obValue   = prgBinding[dwIndex].obStatus + sizeof(DBSTATUS);
    prgBinding[dwIndex].pTypeInfo  = NULL;
    prgBinding[dwIndex].pBindExt   = NULL;
    prgBinding[dwIndex].dwMemOwner = DBMEMOWNER_CLIENTOWNED;
    prgBinding[dwIndex].dwFlags    = 0;
    prgBinding[dwIndex].bPrecision = pDBColumnInfo[dwOrdinal].bPrecision;
    prgBinding[dwIndex].bScale     = pDBColumnInfo[dwOrdinal].bScale;

///////////////////////////////////////////////////////////////////////
// Case-specific binding information has been removed.
///////////////////////////////////////////////////////////////////////

    prgBinding[dwIndex].pObject    NULL;
    prgBinding[dwIndex].wType     = pDBColumnInfo[dwOrdinal].wType;
    if(DBTYPE_WSTR == pDBColumnInfo[dwOrdinal].wType)
    {
        prgBinding[dwIndex].cbMaxLen  = pDBColumnInfo[dwOrdinal].ulColumnSize 
            * sizeof(WCHAR); 
    }
    else
    {
        prgBinding[dwIndex].cbMaxLen  = pDBColumnInfo[dwOrdinal].ulColumnSize; 
    }

    // Calculate and align the offset. 
}

// Get IAccessor interface.
hr = pIRowset->QueryInterface(IID_IAccessor, (void**)&pIAccessor);
if(FAILED(hr))
{
    goto Exit;
}

// Create the accessor.
hr = pIAccessor->CreateAccessor(DBACCESSOR_ROWDATA, dwBindingSize, 
    prgBinding, 0, &hAccessor, NULL);
if(FAILED(hr))
{
    goto Exit;
}

// Allocate data buffer for seek and retrieve operation.
pData = (BYTE*)CoTaskMemAlloc(dwOffset);
if (NULL == pData)
{
    hr = E_OUTOFMEMORY;
    goto Exit;
}

// Set data buffer to zero.
//
memset(pData, 0, dwOffset);

// Set data buffer for seek operation by specifying the 
// dwEmployeeID variable that is passed to the function.
*(DBLENGTH*)(pData+prgBinding[0].obLength)    = 4;
*(DBSTATUS*)(pData+prgBinding[0].obStatus) = DBSTATUS_S_OK;
*(int*)(pData+prgBinding[0].obValue)       = dwEmployeeID;

// Seek for the first row where the value of the selected column 
// is dwEmployeeID. 
hr = pIRowsetIndex->Seek(hAccessor, 1, pData, DBSEEK_FIRSTEQ);
if(FAILED(hr))
{
    goto Exit;    
}

// Retrieve a row handle for the row resulting from the seek.
hr = pIRowset->GetNextRows(DB_NULL_HCHAPTER, 0, 1, &cRowsObtained, 
    &prghRows);
if(FAILED(hr))
{
    goto Exit;    
}

///////////////////////////////////////////////////////////////////////
// Perform programming logic here on the 
// returned rowset, and then release the rowset.
///////////////////////////////////////////////////////////////////////

Exit:

///////////////////////////////////////////////////////////////////////
// This is where the resources are released.
///////////////////////////////////////////////////////////////////////

return hr;

请参阅

概念

OLE DB 索引 (SQL Server Compact)