2010-06-07 7 views
1

J'ai une simple déclaration d'insertion SQL de la forme:Pourquoi "insérer (...) valeurs (...)" n'a pas pu insérer une nouvelle ligne?

insert into MyTable (...) values (...) 

Il est utilisé à plusieurs reprises pour insérer des lignes et fonctionne habituellement comme prévu. Il insère exactement 1 ligne dans MyTable, qui est également la valeur renvoyée par l'instruction Delphi AffectedRows: = myInsertADOQuery.ExecSQL.

Après un certain temps, il y avait un problème de connectivité réseau temporaire. Par conséquent, d'autres threads de la même application ont perçu EOleExceptions (Échec de connexion, -2147467259 = erreur non spécifiée). Plus tard, la connexion réseau a été rétablie, ces threads reconnectés et étaient bien.

Le thread responsable de l'exécution de l'instruction d'insertion décrite ci-dessus n'a cependant pas perçu les problèmes de connectivité (aucune exception) - probablement il n'a tout simplement pas été exécuté alors que le réseau était arrêté. Mais après les problèmes de connectivité réseau, myInsertADOQuery.ExecSQL renvoyait toujours 0 et aucune ligne n'était plus insérée dans MyTable. Après un redémarrage de l'application, l'instruction d'insertion a de nouveau fonctionné comme prévu.

Pour SQL Server, existe-t-il un cas défini dans lequel une instruction d'insertion comme celle ci-dessus n'insère pas de ligne et renvoie 0 comme nombre de lignes affectées? La clé primaire est un GUID autogénéré. Il n'y a pas de contraintes uniques ou de vérification (ce qui devrait entraîner une exception de toute façon plutôt que de ne pas insérer une ligne).

Y a-t-il des bogues ADO connus (Fournisseur = SQLOLEDB.1)?

Autres explications de ce comportement?

Merci, Nang.

+0

avez-vous trace le résultat avec l'outil SQL profileur qui vient avec SQL Server? La première réponse à cette question a une vidéo expliquant comment faire cela: http://stackoverflow.com/questions/504326/trace-file-how-to-use-it –

+0

Non, je ne l'ai pas fait. Merci pour l'indice. Si cela se reproduit, je vais essayer. – nang

Répondre

1

Si les valeurs que vous essayez d'insérer sont violaient

  • une contrainte CHECK
  • une relation de clé étrangère
  • une contrainte NOT NULL
  • une contrainte UNIQUE

ou toute autre contrainte, la ou les lignes ne seront pas insérées.

+0

Merci! Vrai. Mais alors je m'attendrais à une exception, plutôt que d'insérer silencieusement une rangée. Mais à part cela, il n'y a pas de telles contraintes. – nang

1

Utilisez-vous des transactions? Peut-être que votre application n'a pas autocommit? Certains pilotes ne transmettent pas de données s'il y a eu une erreur dans la transaction.

+0

Merci. Aucune transaction explicite utilisée, mais autocommit. Si j'utilisais des transactions, ExecSQL devrait renvoyer 1 pour le nombre de lignes affectées de toute façon, n'est-ce pas? – nang

2

Si vous n'avez pas des exceptions, puis:

  1. Lorsqu'une table a des déclencheurs sans SET NOCOUNT ON, puis en fait l'opération (INSERT/UPDATE/DELETE) peut être terminé avec succès, mais un certain nombre de les enregistrements affectés peuvent être renvoyés sous la forme 0.
  2. En fonction d'une activité de transaction dans la session en cours, les autres sessions peuvent ne pas voir les modifications apportées par la session en cours. Mais la session en cours verra les changements propres et un certain nombre de dossiers concernés sera (peut-être) pas 0.

Ainsi, la réponse exacte peut dépendre de votre table DDL (+ déclenche le cas échéant) et sur la façon dont vous êtes vérifier les lignes insérées.

+0

Merci. 1. Aucun déclencheur utilisé. 2. Ni la session en cours n'observe les lignes insérées, ni les sessions externes. Je vérifie le nombre de lignes insérées par la valeur de retour de MyQuery.ExecSQL. En outre, j'ai vérifié la table pour de nouvelles lignes via le SQL Management Studio - pas de nouvelles lignes. En outre, dans des circonstances normales tout fonctionne bien. Donc je suppose qu'il se passe quelque chose d'étrange au niveau ADO/fournisseur, plutôt qu'au niveau SQL/SQL Server. – nang

+0

Etes-vous capable de reproduire votre problème? –

+0

Au début, tout fonctionnait bien. Ensuite, le problème s'est produit pour la première fois. À partir de ce moment, il était permanent jusqu'à ce que je redémarre ma demande. Depuis lors, je ne suis pas capable de le reproduire. – nang

2

On dirait que votre fil d'insertion a perdu silencieusement la connexion et ne contrôle pas sur elle pour faire une reconnexion automatique si nécessaire, mais ne cesse de faire la queue les inserts sans les envoyer réellement.
Je voudrais isoler ce code dans une petite application autonome pour le déboguer et voir comment il se comporte lorsque vous déconnectez volontairement le réseau puis reconnectez-le.
Je ne serais pas surpris si vous avez trouvé une exception "avalé", ou du code omettant de vérifier le succès/l'échec.
Hope it helps ...

+0

Cela semble raisonnable. Ce que je n'ai pas encore décrit: Lorsque j'ai fermé l'application, certaines fuites de mémoire ont été signalées, y compris ~ 45 TADOCommand et ~ 45 instances TADOQuery. Je me demande juste où l'exception aurait pu être avalée, certainement pas dans mon code d'utilisateur. Dans des circonstances normales, dès que la connexion est rompue, toutes les tentatives ultérieures d'exécution d'une requête aboutissent à une exception. – nang

Questions connexes