IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Comportement bizarre de ExecuteNonQuery


Sujet :

C#

  1. #1
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut Comportement bizarre de ExecuteNonQuery
    Bonjour,

    Dans l'optique de migrer d'un serveur à un autre nous avons développé un outils pour simplifier le travail de l'administrateur.
    Cet outil permet entres autres choses d'attacher les bases de données qui se trouvent dans un répertoire.

    La chaine de connexion à toujours la forme ci-dessous et l'utilisateur m'a dit qu'il se connecte avec le compte "sa" :
    Server=xxxx;Database=master;User ID=yyyy;Password=zzzz


    Le code ci-dessous a été testé sous différents environnements et semblait parfaitement fonctionner jusqu'à présent.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
     
            public Boolean AttachDatabases(IEnumerable<DatabaseInformation> databases)
            {
                if (databases == null) throw new ArgumentNullException("databases");
     
                FillLog("Attachement des bases de données.");
                Boolean result = false;
                using (SqlConnection connection = new SqlConnection(connectionString))
                {
                    using (SqlCommand command = new SqlCommand("SP_ATTACH_DB @DBNAME = @DATABASE, @FILENAME1 = @MDFFILE, @FILENAME2 = @LDFFILE", connection))
                    {
                        connection.Open();
                        command.CommandTimeout = 0;
     
                        SqlParameter name = command.Parameters.Add("DATABASE", SqlDbType.VarChar);
                        SqlParameter mdf = command.Parameters.Add("MDFFILE", SqlDbType.VarChar);
                        SqlParameter ldf = command.Parameters.Add("LDFFILE", SqlDbType.VarChar);
     
                        foreach (DatabaseInformation database in databases)
                        {
                            String message = Environment.NewLine 
                                + "Base de données " + database.Name + Environment.NewLine
                                + "Fichier de données : " + database.ModelDataFile + Environment.NewLine
                                + "Fichier journal : " + database.LogDataFile + Environment.NewLine;
     
                            try
                            {
     
                                name.Value = database.Name;
                                mdf.Value = database.ModelDataFile;
                                ldf.Value = database.LogDataFile;
     
                                command.ExecuteNonQuery();
     
                                message += "Base attachée avec succès.";
                                result = true;
                            }
                            catch (SqlException ex)
                            {
                                result = false;
                                message += ex.Message;
                                FillErrorsList(ex.Message);
                            }
     
                            FillLog(message);
                        }
                    }
                }
    Ce code a été testé sur différentes machines allant d'un Windows Server 2003 avec du SQL Server 2005 jusqu'à du Windows Server 2012 avec SQL Server 2014 et comme je le disais précédemment, il n'y avait eu aucun souci jusqu'à présent.

    On m'a remonté ce message d'erreur sur une machine virtuelle en Windows Server 2008 R2 en 64 bits avec SP1 et SQL Server 2008 R2 :
    System.InvalidOperationException: ExecuteNonQuery nécessite une Connection ouverte et disponible. La connexion est actuellement fermée.
    à System.Data.SqlClient.SqlCommand.ValidateCommand(String method, Boolean async)
    à System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(TaskCompletionSource`1 completion, String methodName, Boolean sendToPipe, Int32 timeout, Boolean asyncWrite)
    à System.Data.SqlClient.SqlCommand.ExecuteNonQuery()
    à XXX.YYY.ZZZ.ServerInstanceManager.AttachDatabases(IEnumerable`1 databases)
    J'avoue ne pas comprendre pourquoi le message dit que la connexion est fermée alors que le Open() est bien passé !
    Si quelqu'un a une idée...

    Merci.

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Août 2010
    Messages
    479
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2010
    Messages : 479
    Points : 762
    Points
    762
    Par défaut
    Visiblement la connexion est ouverte avec succès puis fermée par la suite...
    Le comportement est systématique ou bien de temps en temps ça passe ?
    Une gestion/règle particulière au niveau du serveur peut-être ?

  3. #3
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    Bonjour et merci.

    Le comportement est systématique.
    L'utilisateur m'affirme avoir suivi la FMP que nous lui avons fourni alors je dirais qu'il n'y a pas de réglage spécial mais je n'ai hélas pas de moyen de le vérifier.

  4. #4
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    regarde dans le log d'sql server via management studio pour voir s'il y a des traces d'erreur qui indiqueraient peut-être une incompatibilité (services packs à jours ?)
    sinon un coup de profiler peut peut-être aider aussi ...
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    regarde dans le log d'sql server via management studio pour voir s'il y a des traces d'erreur qui indiqueraient peut-être une incompatibilité (services packs à jours ?)
    sinon un coup de profiler peut peut-être aider aussi ...
    Bonjour et merci.
    Tu as visé dans le 1000 : le profiler m'indique que la base en question est en version supérieure à celle du SQL Server.
    2015-08-25 10:17:02.60 spid55 Erreur : 948, Gravité : 20, État : 1.
    2015-08-25 10:17:02.60 spid55 The database 'DB10427' cannot be opened because it is version 706. This server supports version 663 and earlier. A downgrade path is not supported.
    La correction qui s'impose est de trapper l'InvalidOperationException.
    C'est d'ailleurs bizarre que ce ne soit pas déjà fait vu que ça fait partie de nos automatismes (je m'éloigne du sujet, désolé).

    Cela ne pose de souci particulier de trapper cette exception mais cela me mets deux questions à l'esprit :
    - Comment récupérer la véritable raison du plantage ?
    - Faut-il pour mieux sécuriser cette opération, que je recrée une connexion à chaque fois ?

  6. #6
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    A présent que je sais comment reproduire j'ai fait un essai.

    C'est plus fourbe que ce que je pensais.
    L'exception qui remonte si je ne gère pas de InvalidOperationException est la connexion fermée.
    Sauf qu'en réalité, il se produit une première InvalidOperationException qui n'est pas remontée à l'IHM et que l'on voit apparaître dans les Logs lorsqu'on gère l'exception.
    Base de données DB10427
    Fichier de données : D:\DATA\DB10427.mdf
    Fichier journal : D:\DATA\DB10427.ldf
    Impossible d'ouvrir le fichier physique "D:\DATA\DB10427.mdf". Erreur du système d'exploitation 2 : "2(Le fichier spécifié est introuvable.)".

    Base de données DB160109
    Fichier de données : D:\PGI01\D160109\DB160109.mdf
    Fichier journal : D:\PGI01\D160109\DB160109.ldf
    La base de données 'DB160109' ne peut pas être ouverte, car sa version est 706. Ce serveur prend en charge la version 663 et les versions précédentes. Un chemin de mise à niveau vers une version antérieure n'est pas pris en charge.
    Impossible d'ouvrir la nouvelle base de données 'DB160109'. Abandon de CREATE DATABASE.

    Base de données DB16010Z
    Fichier de données : D:\DATA\DB16010Z.mdf
    Fichier journal : D:\DATA\DB16010Z.ldf
    ExecuteNonQuery nécessite une Connection ouverte et disponible. La connexion est actuellement fermée.

    Base de données DB240B64
    Fichier de données : D:\DATA\DB240B64.mdf
    Fichier journal : D:\DATA\DB240B64.ldf
    ExecuteNonQuery nécessite une Connection ouverte et disponible. La connexion est actuellement fermée.

    Base de données DB98407
    Fichier de données : D:\DATA\DB98407.mdf
    Fichier journal : D:\DATA\DB98407.ldf
    ExecuteNonQuery nécessite une Connection ouverte et disponible. La connexion est actuellement fermée.
    A la vision de ce log, ça me confirme qu'il faut que j'ouvre et referme une connexion à chaque fois.
    Pour moi c'est résolu.
    Merci à vous.

  7. #7
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 154
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 154
    Points : 25 072
    Points
    25 072
    Par défaut
    la connexion ne se ferme pas après l'ouverture, qui est autorisée, c'est le sp_attach qui plante

    aussi le mieux serait de vérifier avant sp_attach la version ou autre pour savoir si ca va passer
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  8. #8
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 152
    Points : 7 402
    Points
    7 402
    Billets dans le blog
    1
    Par défaut
    La connexion est fermée car en SQL, on peut indiquer ce qu'il doit se passer après une erreur. Entre autres, selon la gravité, l'erreur peut mettre fin, ou non, à la session. Visiblement, quand sp_attach plante, il ferme la connexion.

    Bon, outre la gestion propre de l'erreur, le mieux serait peut-être, éventuellement, de l'éviter, non ?

    Ici, la base a été créée avec une version donnée de SQL Server, et vous tentez de l'attacher sur une version antérieure.

    Il faudrait penser à vous mettre dans un schéma plus homogène :
    - Soit en mettant à jour tous les serveurs à la même version
    - Soit en ne travaillant qu'avec des bases de données dans un mode de compatibilité accessible à toutes les versions de vos SQL Servers déployés.
    On ne jouit bien que de ce qu’on partage.

  9. #9
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    Citation Envoyé par Pol63
    la connexion ne se ferme pas après l'ouverture, qui est autorisée, c'est le sp_attach qui plante

    aussi le mieux serait de vérifier avant sp_attach la version ou autre pour savoir si ca va passer
    Ce cas là n'est jamais arrivé auparavant et en général, lors d'une migration, on garde la même licence de SQL Server ou alors on en achète une plus récente.
    J'ai du mal à imaginer qu'un client disposant d'une licence SQL Server 2012 puisse revenir en arrière pour prendre un SQL Server 2008.
    A mon avis, il y a dû avoir un mic mac avec l'assistance technique.
    Bref, c'est un cas exceptionnel qui je pense devrait être gérer par une exception plutôt que de faire une instruction en plus, qui ne sera utile que 0,1% du temps.
    Mais s'il y a un moyen de connaître la version de la base alors que celle-ci n'est pas attachée (même si dans ce cas là, l'option ne me semble pas la bonne), l'informations pourrait être utile (on ne sais jamais) et je serais ravi que tu combles mes lacunes.

    Citation Envoyé par StringBuilder
    La connexion est fermée car en SQL, on peut indiquer ce qu'il doit se passer après une erreur. Entre autres, selon la gravité, l'erreur peut mettre fin, ou non, à la session. Visiblement, quand sp_attach plante, il ferme la connexion.

    Bon, outre la gestion propre de l'erreur, le mieux serait peut-être, éventuellement, de l'éviter, non ?

    Ici, la base a été créée avec une version donnée de SQL Server, et vous tentez de l'attacher sur une version antérieure.

    Il faudrait penser à vous mettre dans un schéma plus homogène :
    - Soit en mettant à jour tous les serveurs à la même version
    - Soit en ne travaillant qu'avec des bases de données dans un mode de compatibilité accessible à toutes les versions de vos SQL Servers déployés.
    Le choix de la version de SQL Serveur n'est pas de mon ressors, c'est le client qui choisit et s'il a une licence pour une version, nous ne pouvons pas lui imposer d'en prendre une plus récente à moins que soit déraisonnable de ne pas le faire (SQL Serveur 2005 minimum).
    - Le mode de compatibilité est déjà géré. Mais ce pourrait être une piste non négligeable dans le cas où une mise à jour soit mal passée.

  10. #10
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    Juste pour information.
    Le niveau de compatibilité n'est pas en cause (si on parle bien tous les deux du niveau indiqué dans l'onglet "Options" de la fenêtre de propriétés)

  11. #11
    Expert éminent
    Avatar de StringBuilder
    Homme Profil pro
    Chef de projets
    Inscrit en
    Février 2010
    Messages
    4 152
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Chef de projets
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2010
    Messages : 4 152
    Points : 7 402
    Points
    7 402
    Billets dans le blog
    1
    Par défaut
    En effet, ce n'est pas un problème de version du moteur, mais du fichier.
    http://stackoverflow.com/questions/1...on-706-asp-net

    Visiblement le MDF a été créé sur un serveur 2012, et le client tente de le monter sur un 2008R2.

    Le plus simple, c'est de conserver chez vous un serveur avec la plus ancienne version par rapport à celles utilisées par vos clients, et gérer vos MDF à partir de ce serveur.
    On ne jouit bien que de ce qu’on partage.

  12. #12
    Expert confirmé
    Avatar de popo
    Homme Profil pro
    Analyste programmeur Delphi / C#
    Inscrit en
    Mars 2005
    Messages
    2 670
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Analyste programmeur Delphi / C#
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2005
    Messages : 2 670
    Points : 5 239
    Points
    5 239
    Par défaut
    Nous conservons évidemment une licence de chacune des versions du moteur que nous validons.

    Cependant, le client reste responsable de ces bases de données.
    Cette fonctionnalité a simplement pour but d'aider l'administrateur à détacher les différentes bases en une seule fois et à les rattacher en une seule fois sur un autre serveur.
    Nous n'intervenons pas dans ce processus. Nous fournissant simplement un moyen plus rapide de le faire.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Comportement bizarre de mes FPS
    Par Ekinoks dans le forum OpenGL
    Réponses: 7
    Dernier message: 22/08/2005, 15h14
  2. xsl:test .... avec comportement bizarre
    Par Blue LC dans le forum XMLRAD
    Réponses: 2
    Dernier message: 10/06/2005, 13h56
  3. [ACESS][MEMO][ISNULL]Comportement bizarre
    Par seb.49 dans le forum ASP
    Réponses: 2
    Dernier message: 09/06/2004, 10h44
  4. [HttpClient] comportement bizarre, saute des catch()...
    Par iubito dans le forum Développement Web en Java
    Réponses: 4
    Dernier message: 04/02/2004, 15h25
  5. [Sybase] Comportement bizarre d'une table
    Par sdozias dans le forum Sybase
    Réponses: 4
    Dernier message: 03/02/2004, 10h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo