J'ai rencontré un comportement surprenant en utilisant ADO avec C++ et Microsoft SQL Server 2008 (express). Essentiellement, j'avais du code qui faisait ceci :
//pseudocode pseudocode pseudocode
adoConnection->Execute("BEGIN TRANSACTION;");
Insert( adoRecordsetPtr );
SelectAll( adoRecordsetPtr );
adoConnection->Execute("COMMIT TRANSACTION;");
Mais lorsqu'il a essayé d'exécuter le SelectAll, ADO a déclenché une exception avec les informations suivantes :
Erreur : Erreur ADO -2147217871 : 071A14D0
De la source : Microsoft OLE DB Provider for SQL Server
Description : Le délai d'attente a expiré
Après quelques recherches, j'ai découvert que si j'utilisais ado_connection->BeginTrans(), comme le ferait une personne saine d'esprit, tout fonctionnait comme prévu. Et bien que ce post soit surtout là pour rendre la solution de contournement googlelisable pour d'autres personnes qui pourraient la rencontrer, j'ai aussi une question :
Pourquoi cela a-t-il réglé le problème ?
Voici un peu plus de détails sur ce qui se passe avec mon Insert et mon SelectAll. Notez que SelectAll utilise un objet de commande ADO (car dans le code actuel, il ne s'agit pas d'une sélection). Le délai d'attente ne se produit pas si j'utilise Connection.Execute() au lieu de 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 );