【发布时间】:2010-10-22 15:12:31
【问题描述】:
在将 ADO 与 C++ 和 Microsoft SQL Server 2008 (express) 一起使用时,我遇到了一些令人惊讶的行为。本质上,我有这样做的代码:
//pseudocode pseudocode pseudocode
adoConnection->Execute("BEGIN TRANSACTION;");
Insert( adoRecordsetPtr );
SelectAll( adoRecordsetPtr );
adoConnection->Execute("COMMIT TRANSACTION;");
但是当它试图执行 SelectAll 时,ADO 抛出了异常,并显示以下信息:
错误:ADO 错误 -2147217871:071A14D0
来源:Microsoft OLE DB Provider for SQL Server
说明:超时过期
经过一番调查,我发现如果我像正常人一样使用 ado_connection->BeginTrans(),一切都会按预期进行。虽然这篇文章主要是为了让其他可能遇到它的人可以用谷歌搜索解决方法,但我还有一个问题:
为什么这能解决问题?
这里有一些关于我的 Insert 和 SelectAll 发生了什么的更多细节。请注意,SelectAll 使用的是 ADO 命令对象(因为在实际代码中它没有执行全选)。如果我使用 Connection.Execute() 而不是 Command.Execute(),则不会发生超时。
//Insert
ADODB::_RecordsetPtr prs = NULL;
HRESULT hr = prs.CreateInstance(__uuidof(ADODB::Recordset));
prs->Open(
table
_variant_t((IDispatch *) acpAdoConnection),
ADODB::adOpenUnspecified,
ADODB::adLockOptimistic,
ADODB::adCmdTable);
prs->AddNew();
//put some stuff into fields using prs->Fields->Item[]
prs->Update();
prs->Close();
//SelectAll
ADODB::_CommandPtr cmd;
cmd.CreateInstance( __uuidof( ADODB::Command ) );
cmd->ActiveConnection = acpAdoConnection;
ADODB::_RecordsetPtr prs2 = NULL;
HRESULT hr2 = prs2.CreateInstance(__uuidof(ADODB::Recordset));
prs2->Open(
table,
_variant_t((IDispatch *) acpAdoConnection),
ADODB::adOpenUnspecified,
ADODB::adLockOptimistic,
ADODB::adCmdTable);
std::string sql = "SELECT * FROM [" + table + "] ;";
cmd->CommandText = sql.c_str();
_variant_t vtEmpty (DISP_E_PARAMNOTFOUND, VT_ERROR);
_variant_t vtEmpty2(DISP_E_PARAMNOTFOUND, VT_ERROR);
//timeout:
ADODB::_RecordsetPtr records =
cmd->Execute( &vtEmpty, &vtEmpty2, ADODB::adCmdText );
【问题讨论】:
标签: c++ sql-server ado