8
votes

SQL Server and .NET: Insérer échoue (silencieusement!) Dans le code mais pas quand on fonctionne manuellement

Ma procédure stockée d'insertion:

SqlCommand cmd = CreateCommand(procName, prams);
object result = cmd.ExecuteScalar();


0 commentaires

6 Réponses :


3
votes

Placez le profileur SQL Server pour voir ce qui se passe dans la DB.


1 commentaires

Grande idée, merci, cela a beaucoup aidé (voir la mise à jour de la question).



6
votes

La colonne d'identité sera incrémentée chaque fois qu'un insert est tenté, même si elle échoue, de sorte que la partie n'est pas nécessairement inhabituelle.

Je cherche des problèmes avec vos valeurs de paramètre et / ou des types dans Arrparams. Quel type d'objet est 'données'? (J'ai presque peur de demander, mais je ne reçois aucun succès sur MSDN pour ExecuteInscalar)

edit:

Je pense que VAN est sur la bonne voie en ce qui concerne la transaction ne pas être commise. Il vous échappe comme vous utilisez une sorte de classe d'assistance personnalisée pour gérer les appels vers des procédures stockées dans la base de données (et d'autres accès à la base de données, vraisemblablement), ce qui pourrait être que ce code avale l'erreur soulevée par SQL Server. J'ai créé une petite application de test et j'ai pu reproduire le comportement que vous décrivez. Puisque nous ne pouvons pas dire comment votre classe piège des exceptions, etc. Cela peut ne pas être votre problème réel, mais c'est une façon d'appeler une procédure stockée pourrait échouer dans la manière dont vous décrivez. < Pré> xxx

Les transactions ne doivent pas être explicitement déclarées. Par exemple, si vous avez supprimé les appels à Begintransaction () et transaction.commit () à partir du code ci-dessus, une transaction implicite pourrait toujours être interrompue théoriquement et causée au dos. Donc, la racine de votre problème pourrait être plus subtile que cet exemple, ce qui nécessite une transaction explicite pour démontrer le concept.

Plus pratiquement, vous pouvez voir (via Profiler) le SQL réel que l'application envoie à la SQL Server et vérifiez qu'il fonctionne lorsqu'il fonctionne lorsqu'il est exécuté de SSMS, cela me fait penser que le problème est probablement avec le code de l'application qui appelle la procédure stockée.


2 commentaires

Je ne reçois aucun succès sur MSDN pour ExecuteInscalar Damn, désolé! J'aurais dû mentionner que c'est une méthode qui a fait que quelqu'un appelle essentiellement juste des appels sqlcommand.exectescalar () . Désolé pour la confusion!


C'est ça! La classe d'assistance manquait une cmd.transaction.commit () dans l'une de ses fonctions!



1
votes

pourrait être que vous roulez une transaction. Cela expliquerait pourquoi la ligne n'est pas présente. Je ne pense pas que proj_ins_all échoue si vous êtes capable d'observer que la variable _id est définie. Si une exception a été lancée, cela ne se produirait pas. Donc, il doit être le cas où une transaction est en vigueur et est en cours de roulé.


2 commentaires

la variable _id est définie. Si une exception a été lancée, cela ne se produirait pas. - Exactement, c'est ce que je pensais aussi, mais cela se révèle que c'est en fait ce qui se passait. IMHO très étrange (voir question mise à jour).


Désolé mon mauvais - c'était la transaction après tout (ou plutôt mal de mon prédeccessor qui a utilisé des transactions pour certaines de ses méthodes et non d'autres, ce qui me convaincait que le code que j'utilisais n'utilisait pas une transaction, quand elle était en réalité).



6
votes

soit votre transaction est pas commis ou l'exception est lancée et est juste mangé (ignoré).


4 commentaires

Une idée pourquoi il pourrait être ignoré? Puis-je changer une variable sur SQL Server ON ou OFF pour l'obtenir pour ne pas masquer les erreurs importantes?


Premières choses d'abord: Assurez-vous de commettre la transaction. Si toujours le même, débogez un code .NET pour voir si l'exception est lancée (pendant l'exécution ... (...)). Ou simplement envelopper votre appel en pratiquez et enregistrez l'erreur. Je n'ai pas vu SqlServer juste en silence et ne pas notifier un client / appelant. Donc, si ce n'est pas un commit, il est probablement probablement sur votre code .NET et non SQLServer.


Désolé mon mauvais - c'était la transaction après tout (ou plutôt mal de mon prédeccessor qui a utilisé des transactions pour certaines de ses méthodes et non d'autres, ce qui me convaincait que le code que j'utilisais n'utilisait pas une transaction, quand elle était en réalité).


NP, la seule chose importante est que vous avez trouvé le problème. À votre santé.



0
votes

Si vous avez une valeur DateTime en C #, elle sera transmise sous forme de DateTime sur SQL Server tel quel.

Si vous avez une valeur de chaîne en C # que vous souhaitez transmettre en tant que paramètre DateTime, il passera à travers certaines transformations de localisation Voodoo en fonction des paramètres de langue / de culture de votre système d'exploitation et de votre DB.

Je vous suggère de vous assurer que votre code passe vraiment une valeur DateTime (laquelle vous pouvez vérifier l'exactitude avant d'invoquer le SP).


0 commentaires

0
votes

blockquote

erreur de conversion de type de données Varcharchar en DateTime.

Depuis que je le testais manuellement, j'ai simplement raccourci la dateTime du '2009-09-03 16: 20: 11.7130000' à '2009-09-03 16:20:11' et cela corrige l'erreur; Maintenant, la ligne insérée bien.

BlockQuote Ceci est un bogue dans le profileur SQL. http://support.microsoft.com/kb/974289/


0 commentaires