我尝试立即接收Select语句和记录集的记录数。
Recordset对象为此问题提供RecordCount
属性。
使用静态的服务器端游标可以正常工作,但是如果我在SQL Server Profiler中查看事件,我意识到,它似乎是在获取整个记录集的每一行,只是为了计算行数。
另一方面,我可以在记录集上执行MoveLast,Bookmark
包含最后一行的索引(== Recordcount)。
我不想使用Bookmark而不是RecordCount,并想知道是否有人可以解释这种行为。
如果有人被强迫,我创建了一个小代码示例来重现它:
::CoInitialize(NULL);
ADODB::_ConnectionPtr pConn;
HRESULT hr;
hr = pConn.CreateInstance(__uuidof(ADODB::Connection));
pConn->CursorLocation = ADODB::adUseServer;
pConn->ConnectionTimeout = 0;
pConn->Provider = "SQLOLEDB";
pConn->Open(bstr_t("Provider=sqloledb;Data Source=s11;Initial Catalog=...;Application Name=DBTEST"), "", "", ADODB::adConnectUnspecified);
// Create Command Object
_variant_t vtRecordsAffected;
ADODB::_CommandPtr cmd;
hr = cmd.CreateInstance(__uuidof(ADODB::Command));
cmd->ActiveConnection = pConn;
cmd->CommandTimeout = 0;
// Create a test table
cmd->CommandText = _bstr_t("create table #mytestingtab (iIdentity INT)");
cmd->Execute(&vtRecordsAffected, NULL, ADODB::adCmdText);
// Populate
cmd->CommandText = _bstr_t(
"DECLARE @iNr INT\r\n"
"SET @iNr = 0\r\n"
"WHILE @iNr < 10000\r\n"
"BEGIN\r\n"
" INSERT INTO #mytestingtab (iIdentity) VALUES (@iNr)\r\n"
" SET @iNr = @iNr + 1\r\n"
"END\r\n"
);
cmd->Execute(&vtRecordsAffected, NULL, ADODB::adCmdText);
// Create a Recordset Object
_variant_t vtEmpty(DISP_E_PARAMNOTFOUND, VT_ERROR);
ADODB::_RecordsetPtr Recordset;
hr = Recordset.CreateInstance(__uuidof(ADODB::Recordset));
Recordset->CursorLocation = ADODB::adUseServer;
cmd->CommandText = _bstr_t(
"SELECT * FROM #mytestingtab"
);
Recordset->PutRefSource(cmd);
Recordset->Open(vtEmpty, vtEmpty, ADODB::adOpenStatic, ADODB::adLockReadOnly, ADODB::adCmdText);
// Move to the Last Row
Recordset->MoveLast();
_variant_t bookmark = Recordset->Bookmark;
// Recordcount
long tmp = Recordset->RecordCount;
Recordset->Close();
pConn->Close();
::CoUninitialize();
有没有办法使用Recordset
属性,而不将所有行传输到客户端?