Я столкнулся с неожиданным поведением при использовании ADO с C ++ и Microsoft SQL Server 2008 (экспресс). По сути, у меня был код, который сделал это:
//pseudocode pseudocode pseudocode
adoConnection->Execute("BEGIN TRANSACTION;");
Insert( adoRecordsetPtr );
SelectAll( adoRecordsetPtr );
adoConnection->Execute("COMMIT TRANSACTION;");
Но когда он попытался выполнить SelectAll, ADO выдал исключение со следующей информацией:
Ошибка: ошибка ADO -2147217871: 071A14D0
Из источника: поставщик Microsoft OLE DB для 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 );