Composants ADO CommandTimeout
J'ai un problème avec les paramètres de la requête de délai d'exécution avec TADOQuery, TADOCommand ou TADODataSet (j'ai essayé avec chacun). J'ai une petite application qui se connecte à la base de données et périodiquement exécute des procédures stockées, qui retourne le jeu de données comme un résultat.
Mon but est de garder cette application toujours en ligne, mais mon problème est que lorsque la connexion est perdue, le délai d'attente de simplement la commande en cours d'exécution (par le biais de l'un des composants mentionnés) prend la valeur par défaut de 30 secondes. J'ai été à la recherche de la solution, mais rien ne fonctionne.
Pourriez-vous me donner des conseils, comment définir la CommandTimeout par exemple à 5 secondes, ou pour mieux dire comment modifier ADODB.pas pour le respect de ma propre délai d'attente, s'il vous plaît ?
Il y avait beaucoup de "solutions" pour ce, comme DataComponent.Connexion.CommandTimeout := 1; mais vraiment, rien ne fonctionne. Je suis en utilisant D2009, MSSQL2005 et la connexion avec le composant de données est créé dynamiquement dans le fil.
La dernière, ce que j'ai essayé est ce
// protected variable owned and created in the thread with its own connection
var Query_Object: TADODataSet;
// connection timeout is set to 3 seconds
Query_Object.Connection.ConnectionTimeout := 3;
...
// this piece of code I'm calling periodically in the only one existing thread
...
SQL_Query := 'EXEC my_procedure_which_returns_dataset'
with Query_Object do
begin
Close;
CommandType := cmdText;
CommandText := SQL_Query;
CommandTimeout := 5; // doesn't affect the timeout
CursorLocation := clUseServer; // let the dataset retreives prepared data
Open;
end;
// and here I need to get faster than in the default 15 seconds to let the user
// know that the reading takes more than mentioned 5 seconds
...
Merci beaucoup 🙂
OriginalL'auteur | 2011-02-22
Vous devez vous connecter pour publier un commentaire.
CommandTimeout
est de coups de pied quand vous avez des requêtes de longue durée. Il y a unCommandTimeout
propriété deTADOConnection
mais qui ne fonctionne pas. Vous devez utiliser leCommandTimeout
de laTADODataSet
à la place.Si le serveur est indisponible, votre question dit "perte de connexion", vous devez spécifier
ConnectionTimeout
de laTADOConnection
composant. Le défaut est de 15 secondes, avant que la commande est retournée à votre application.Edit 1 je pense avoir découvert une situation où CommandTimeout ne fonctionne pas. J'ai testé cette contre une très grande table. Il faut plusieurs minutes pour renvoyer toutes les lignes. Si ma procédure stockée ne
select * from BigTable
le délai d'expiration de requête n'arrive jamais. Au moins je n'étais pas assez patient pour attendre que ça passe. Mais si la requête est laselect * from BigTable order by Col1
et il n'y a pas d'index surCol1
, le CommandTimout fonctionne comme prévu.La différence entre les deux requêtes est évident lors de l'exécution dans SSMS. Le premier commence immédiatement retourner lignes et la seconde a besoin de "penser" à ce sujet avant qu'il ne retourne des lignes. Lorsque SQL Server ont trouvé les lignes dont il a besoin et commencer à les retourner, CommandTimeout ne fonctionne pas.
Si vous définissez
CursorLocation
àclUseServer
laCommandTimeout
fonctionnera comme prévu pour les deux requêtes.Mise à jour de répondre avec un peu plus de résultats. Je peux recréer ce que vous vivez.
Il fonctionne très bien, j'ai fait une erreur en quelque chose d'autre (pas d'ADO pertinentes) et après correction j'ai vraiment eu le délai d'attente après TADODataSet.CommandTimeout + TADODataSet.Connexion.ConnectionTimeout. Accepté comme une solution aussi en raison de CursorLocation remarque 🙂 Merci pour votre temps
+1 pour la mention de curseur côté serveur comportement.
OriginalL'auteur Mikael Eriksson
Suivante est ce que nous utilisons pour définir le délai d'attente de 300 pour notre long à exécuter des rapports.
Modifier
L'exécution de morceau de code suivant sur ma Machine de Développement après 1 seconde.
Test
cela fonctionne pour nous mettre 300, mais nous n'avons pas essayé le réglage de < 30. Si je l'ai trouver un peu de temps, je vais vérifier et mes conclusions.
J'ai mis à jour la réponse avec un script qui fonctionne pour moi. Si cela ne fonctionne pas pour vous, il ya quelque chose de mal. Si c'est le cas, vous avez un point de départ pour trouver les différences avec votre code.
oui, peut-être ce qui fonctionne pour ExecSQL, mais je vais essayer d'ouvrir un dataset à l'aide de la méthode Open. À savoir que je veux exécuter la procédure stockée qui renvoie un jeu de résultats. Actuellement je suis venu à la TADODataSet objet (voir ma mise à jour en question).
C'est un simple exemple. Pour notre information, nous utilisons
Open
ioExecSQL
et ont le délais de commande à l'honneur. Cet exemple vous donner un temps? Dit vous trie? Lorsque vous modifier pour Ouvrir io ExecSQL (et de modifier l'instruction sql dans quelque chose qui prend du temps), cela fonctionne t'il?OriginalL'auteur Lieven Keersmaekers
J'ai toujours utilisé le code suivant pour définir la CommandTimeout valeur sur un TADOQuery. Si vous modifiez le nom de la classe, il convient également de travailler avec les autres.
OriginalL'auteur Peter McMinn