none
La conversion du type 'DBNull' en type 'String' n'est pas valide. RRS feed

  • Question

  • Bonjour
    Au cours de l'execution de mon application,une erreur est produite :
    "La conversion du type 'DBNull' en type 'String' n'est pas valide."

    code:

        Function GetFileNameToDelete(Entry_ID As integer) As String
                          Dim SortCommand As String = "SELECT img FROM ArticlesRss WHERE ArticlesRss.ID =" & Entry_ID & ";"
                          Dim conn as New oledbConnection(ConnectionString)
                          Dim objDR as oledbDataReader
                          Dim Cmd as New oledbCommand(SortCommand, conn)
                          conn.Open()
                          objDR=Cmd.ExecuteReader(system.data.CommandBehavior.CloseConnection)
                          While objDR.Read()
                             GetFileNameToDelete=objDR("img")
                          End While
                      End Function

    Bien cordialement

    Michel

    mercredi 14 mai 2014 09:09

Réponses

  • Bonjour, si tu fais conn.Open(), autant faire aussi conn.close(), mais aussi cmd.dispose() après ta boucle While.

    Au sujet de ton erreur, tu as débogué afin de voir d'où venait l'erreur? Si c'est au niveau de ta requête, tu devrais mettre cela dans ta boucle while:

    If IsDBNull(objDR("img")) Then
       getFilleNameToDelete=""
    else
       getFilleNameToDelete=objDR("img")
    End If

    ps: utilise la balise CODE quand tu as du code à afficher

    • Proposé comme réponse Aurel Bera mercredi 14 mai 2014 10:42
    • Marqué comme réponse Aurel Bera lundi 19 mai 2014 06:52
    mercredi 14 mai 2014 09:55
  • Bonjour,

    Voici le code modifié qui devrait fonctionner

       Function GetFileNameToDelete(Entry_ID As Integer) As String
            Dim SortCommand As String = "SELECT img FROM ArticlesRss WHERE ArticlesRss.ID =" & Entry_ID & ";"
            Using conn As New OleDbConnection(ConnectionString)
                Using Cmd As New OleDbCommand(SortCommand, conn)
                    conn.Open()
                    Using objDR = Cmd.ExecuteScalar(System.Data.CommandBehavior.CloseConnection)
                        Return IIf(IsDBNull(objDR("img")), String.Empty, objDR("img"))
                    End Using
                End Using
            End Using
            Throw New ArgumentException("Invalid Entry_ID", "Entry_ID")
        End Function

    Et quelques remarques

    •  Logiquement le select ne devrait renvoyer qu'une seule ligne avec une seule colonne. L'exécution d'un ExecuteScalar semble donc plus approprié. Cela évite l'utilisation d'un while alors que l'on ne doit normalement ne récupérer qu'un item. Toutefois si la reqûete SQL est susceptible de renvoyer plusieurs lignes, alors il faut effectivement un ExecuteReader mais une sortie de méthode qui devrait être un tableau/list/énumérateur de chaînes et non pas une simple chaîne
    • J'ai laissé la fonction renvoyer une chaîne vide lorsqu'elle ne trouve rien. Elle devrait probablement renvoyer un Nothing (un null en C#, C++/CLI, etc) dans ce cas de figure. En effet s'il y a un DBNull en base, c'est qu'il y a bien un "null" à renvoyer quelque part. Je pinaille mais il y a une différence entre ne pas renseigner un champ (valeur null) et volontairement entrer une valeur vide (renseigner qu'il n'y a rien)
    • Si l'Entry_ID n'existe pas en base de données, une exception est levée car il s'agit bien d'un mauvais usage de la fonction
    • L'ExecuteReader a un CommandBehvavior, la connexion sera fermée après l'ExecuteReader, c'est parfait. J'ai  toutefois ajouté des "Using" pour montrer comment être sûr que les ressources non managées soient fermées immédiatement et non lors du Garbage Collect.
    • En effet le Using appelera la méthode Dispose() qui n'a pas le même objectif que le Close(). Ce dernier ferme la connection tandis que le Dispose libère immédiatement la mémoire des ressources sous-jacentes non managées en plus d'appeler le close. Il ne faut par sous-entendre par là une fermeture de la connexion dans le pool, mais bien une optimisation de la gestion des ressources, de la mémoire. 

    Bien cordialement,

    Fabrice



    mercredi 14 mai 2014 16:15
  • Bonjour MicheleMichel

    Est-ce que vous avez testé la solution proposée ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse MicheleMichel samedi 17 janvier 2015 08:08
    jeudi 15 mai 2014 13:05
  • Merci pour votre réponse

    Problème résolu

    Cordialement

    Michel

    • Marqué comme réponse MicheleMichel jeudi 22 janvier 2015 08:55
    samedi 17 janvier 2015 08:10

Toutes les réponses

  • Bonjour, si tu fais conn.Open(), autant faire aussi conn.close(), mais aussi cmd.dispose() après ta boucle While.

    Au sujet de ton erreur, tu as débogué afin de voir d'où venait l'erreur? Si c'est au niveau de ta requête, tu devrais mettre cela dans ta boucle while:

    If IsDBNull(objDR("img")) Then
       getFilleNameToDelete=""
    else
       getFilleNameToDelete=objDR("img")
    End If

    ps: utilise la balise CODE quand tu as du code à afficher

    • Proposé comme réponse Aurel Bera mercredi 14 mai 2014 10:42
    • Marqué comme réponse Aurel Bera lundi 19 mai 2014 06:52
    mercredi 14 mai 2014 09:55
  • Bonjour,

    Voici le code modifié qui devrait fonctionner

       Function GetFileNameToDelete(Entry_ID As Integer) As String
            Dim SortCommand As String = "SELECT img FROM ArticlesRss WHERE ArticlesRss.ID =" & Entry_ID & ";"
            Using conn As New OleDbConnection(ConnectionString)
                Using Cmd As New OleDbCommand(SortCommand, conn)
                    conn.Open()
                    Using objDR = Cmd.ExecuteScalar(System.Data.CommandBehavior.CloseConnection)
                        Return IIf(IsDBNull(objDR("img")), String.Empty, objDR("img"))
                    End Using
                End Using
            End Using
            Throw New ArgumentException("Invalid Entry_ID", "Entry_ID")
        End Function

    Et quelques remarques

    •  Logiquement le select ne devrait renvoyer qu'une seule ligne avec une seule colonne. L'exécution d'un ExecuteScalar semble donc plus approprié. Cela évite l'utilisation d'un while alors que l'on ne doit normalement ne récupérer qu'un item. Toutefois si la reqûete SQL est susceptible de renvoyer plusieurs lignes, alors il faut effectivement un ExecuteReader mais une sortie de méthode qui devrait être un tableau/list/énumérateur de chaînes et non pas une simple chaîne
    • J'ai laissé la fonction renvoyer une chaîne vide lorsqu'elle ne trouve rien. Elle devrait probablement renvoyer un Nothing (un null en C#, C++/CLI, etc) dans ce cas de figure. En effet s'il y a un DBNull en base, c'est qu'il y a bien un "null" à renvoyer quelque part. Je pinaille mais il y a une différence entre ne pas renseigner un champ (valeur null) et volontairement entrer une valeur vide (renseigner qu'il n'y a rien)
    • Si l'Entry_ID n'existe pas en base de données, une exception est levée car il s'agit bien d'un mauvais usage de la fonction
    • L'ExecuteReader a un CommandBehvavior, la connexion sera fermée après l'ExecuteReader, c'est parfait. J'ai  toutefois ajouté des "Using" pour montrer comment être sûr que les ressources non managées soient fermées immédiatement et non lors du Garbage Collect.
    • En effet le Using appelera la méthode Dispose() qui n'a pas le même objectif que le Close(). Ce dernier ferme la connection tandis que le Dispose libère immédiatement la mémoire des ressources sous-jacentes non managées en plus d'appeler le close. Il ne faut par sous-entendre par là une fermeture de la connexion dans le pool, mais bien une optimisation de la gestion des ressources, de la mémoire. 

    Bien cordialement,

    Fabrice



    mercredi 14 mai 2014 16:15
  • Bonjour MicheleMichel

    Est-ce que vous avez testé la solution proposée ? Merci de partager avec nous les résultats, afin que d'autres personnes avec le même problème puissent profiter de cette solution.

    Cordialement,


    Aurel BERA, MSFT
    MSDN Community Support. LE CONTENU EST FOURNI "TEL QUEL" SANS GARANTIE D'AUCUNE SORTE, EXPLICITE OU IMPLICITE.
    S'il vous plaît n'oubliez pas de "Marquer comme réponse" les réponses qui ont résolu votre problème. C'est une voie commune pour reconnaître ceux qui vous ont aidé, et rend plus facile pour les autres visiteurs de trouver plus tard la résolution.

    • Marqué comme réponse MicheleMichel samedi 17 janvier 2015 08:08
    jeudi 15 mai 2014 13:05
  • Merci pour votre réponse

    Problème résolu

    Cordialement

    Michel

    • Marqué comme réponse MicheleMichel jeudi 22 janvier 2015 08:55
    samedi 17 janvier 2015 08:10