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

Développement SQL Server Discussion :

SQL et requête pour remplissage d'un treeview en vb.net


Sujet :

Développement SQL Server

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 24
    Par défaut SQL et requête pour remplissage d'un treeview en vb.net
    Bonjour,

    J'ai un problème mais je ne trouve rien pour le résoudre...
    Mon cas : j'ai un treeview à remplir à partir d'une table dans ma base de données sql (sous sql server 2005).
    Non, ne dites pas que ce topic doit être déplacer en forum DOTNET car le problème vient de la requête SQL.

    Voici la forme de la table :
    colonne idQualif (int) -> identifiant unique clé primaire
    colonne libelle (varchar(50)) -> libelle
    colonne idParent (int) -> numéro d'identifiant du parent (à NULL si noeud root)

    Et en code behind aspx.vb :

    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
    49
    50
    51
    52
    Imports System.Data.SqlClient
    Imports System.Data
    
    Partial Class qualification
        Inherits System.Web.UI.Page
    
        Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            If Not Page.IsPostBack Then
                PopulateRootLevel()
            End If
        End Sub
    
        Private Sub PopulateRootLevel()
            Dim objConn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("ChaineConnection").ConnectionString)
            Dim objCommand As New SqlCommand("select idQualification, libelle, (select count(*) FROM qualificationLibelle qL WHERE idParent=qL.idQualification) childnodecount FROM qualificationLibelle WHERE idParent IS NULL", objConn)
    
            Dim da As New SqlDataAdapter(objCommand)
            Dim dt As New DataTable()
            da.Fill(dt)
    
            PopulateNodes(dt, TreeView1.Nodes)
        End Sub
    
        Private Sub PopulateSubLevel(ByVal idParent As Integer, ByVal parentNode As TreeNode)
            Dim objConn As New SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings("ChaineConnection").ConnectionString)
            Dim objCommand As New SqlCommand("select idQualification, libelle, (select count(*) FROM qualificationLibelle qL WHERE idParent=qL.idQualification) childnodecount FROM qualificationLibelle WHERE idParent=@idParent", objConn)
            objCommand.Parameters.Add("@idParent", SqlDbType.Int).Value = idParent
    
            Dim da As New SqlDataAdapter(objCommand)
            Dim dt As New DataTable()
            da.Fill(dt)
            PopulateNodes(dt, parentNode.ChildNodes)
        End Sub
    
        Private Sub PopulateNodes(ByVal dt As DataTable, ByVal nodes As TreeNodeCollection)
            For Each dr As DataRow In dt.Rows
                Dim tn As New TreeNode()
                tn.Text = dr("libelle").ToString()
                tn.Value = dr("idQualification").ToString()
                nodes.Add(tn)
    
                'If node has child nodes, then enable on-demand populating
                tn.PopulateOnDemand = (CInt(dr("childnodecount")) > 0)
            Next
        End Sub
    
    
        Protected Sub TreeView1_TreeNodePopulate(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.TreeNodeEventArgs) Handles TreeView1.TreeNodePopulate
            PopulateSubLevel(CInt(e.Node.Value), e.Node)
        End Sub
    
    End Class
    La première requête en rouge doit sélectionner l'id et le libelle et le nombre de fils des noeuds root. Cependant, le (select count (*)...) renvoi toujours 0.
    La deuxième requête en rouge doit sélectionner l'id et le libelle et le nombre de fils des noeuds suivants. Cependant, le (select count (*)...) renvoi toujours 0.


    Lorsque j'essaye d'afficher mon arbre, je vois seulement les 2 noeuds root sous la forme :
    ..... Noeud 1
    |
    ..... Noeud 2


    Pouvez-vous m'aider à construire ma requête ???

    Merci

  2. #2
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Bonjour,

    Outre le fait que votre requête contient une jointure triangulaire, il est normal qu'elle vous retourne 0 puisque vous recherchez idParent = qL.idQualification avec WHERE idParent IS NULL.
    Or NULL n'est pas une valeur, c'est une propriété qui spécifie l'absence de valeur. Ainsi, si vous testez NULL = NULL, ce sera toujours faux.

    Écrivez vos requêtes en utilisant COUNT mais avec la clause GROUP BY, c'est à dire sans sous-requête .

    @++

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 24
    Par défaut
    Citation Envoyé par CTEMan Voir le message
    Bonjour,

    Outre le fait que votre requête contient une jointure triangulaire, il est normal qu'elle vous retourne 0 puisque vous recherchez idParent = qL.idQualification avec WHERE idParent IS NULL.
    Or NULL n'est pas une valeur, c'est une propriété qui spécifie l'absence de valeur. Ainsi, si vous testez NULL = NULL, ce sera toujours faux.

    Écrivez vos requêtes en utilisant COUNT mais avec la clause GROUP BY, c'est à dire sans sous-requête .

    @++

    J'ai changé le NULL en = 0 .
    Le résultat ne change pas, je n'ai toujours que mes 2 noeuds root qui s'affichent.

    Pouvez-vous m'aider à construire la requête ? Car je ne vois pas comment faire, childnodecount n'est pas une colonne, je ne vois pas comment faire le count avec le group by...

    Merci de l'attention que vous y portez !

  4. #4
    Membre chevronné Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Par défaut Représentation intervallaire ?
    Bonsoir,

    Si votre abrorescence est surtout accédée en lecture.

    Avez vous lu cet article de SQLPro ?

    Vous y trouverez comment gérer un arbre en SQL, bien plus proprement qu'avec une auto jointure, sans problème de récursivité, et aussi toutes les requêtes nécessaires.

    @+

  5. #5
    Modérateur

    Homme Profil pro
    Administrateur de base de données
    Inscrit en
    Janvier 2005
    Messages
    5 826
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Administrateur de base de données
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Janvier 2005
    Messages : 5 826
    Par défaut
    Voici le lien que vous propose agemis31

    Pour pouvoir effectuer des tests, je me suis muni de la table suivante :

    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
    CREATE TABLE TEST
    (
    	idQualif INT NOT NULL,
    	libelle VARCHAR(50) NOT NULL,
    	idParent INT
    )
    GO
     
    INSERT INTO dbo.TEST VALUES(1, 'TOTO', NULL)
    INSERT INTO dbo.TEST VALUES(2, 'TITI', 1)
    INSERT INTO dbo.TEST VALUES(3, 'TUTU', 1)
    INSERT INTO dbo.TEST VALUES(4, 'GRINGO', NULL)
    INSERT INTO dbo.TEST VALUES(5, 'GRINGA', 4)
    INSERT INTO dbo.TEST VALUES(6, 'GRINGALET', 4)
    INSERT INTO dbo.TEST VALUES(7, 'GRINGOULET', 4)
    Vous pourriez remplacer la 1e requête par celle-ci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    WITH
    	CTE AS
    	(
    		SELECT idParent,
    				COUNT(*) AS nbNodes
    		FROM dbo.TEST
    		GROUP BY idParent
    	)
    SELECT T.idQualif,
    		T.libelle,
    		CTE.nbNodes
    FROM CTE
    JOIN dbo.TEST AS T ON CTE.idParent = T.idQualif
    Le mieux étant de l'encapsuler dans une procédure stockée pour les raisons suivantes.
    Cela donnerait alors :

    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
    CREATE PROCEDURE Ps_Qualif_GetParentNodes
    AS
    BEGIN
    	WITH
    		CTE AS
    		(
    			SELECT idParent,
    					COUNT(*) AS nbNodes
    			FROM dbo.TEST
    			GROUP BY idParent
    		)
    	SELECT T.idQualif,
    			T.libelle,
    			CTE.nbNodes
    	FROM CTE
    	JOIN dbo.TEST AS T ON CTE.idParent = T.idQualif
    END
    Et vous pouvez faire appel à celle-ci en précisant dans votre code VB.NET que objCommand est de type SqlCommand.StoredProcedure (si ma mémoire est bonne )

    Avec le jeu de données que j'ai donné en début de post, cela retourne :

    idQualif libelle nbNodes
    -------------------------------
    1 TOTO 2
    4 GRINGO 3
    Partons maintenant à la recherche du nombre d'enfants quand une node mère a été choisie : la procédure stockée correspondante serait alors :

    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
    CREATE PROCEDURE Ps_Qualif_GetChildNodes
    	@idParentNode INT
    AS
    BEGIN
    	WITH
    		CTE AS
    		(
    			SELECT idParent,
    					COUNT(*) AS nbNodes
    			FROM dbo.TEST
    			GROUP BY idParent
    		)
    	SELECT T.idQualif,
    			T.libelle,
    			CTE.nbNodes
    	FROM CTE
    	JOIN dbo.TEST AS T ON CTE.idParent = T.idQualif
    	WHERE idQualif = @idParentNode
    END
    Avec le jeu de données que j'ai donné en début de post, cela retourne :

    idQualif libelle nbNodes
    --------------------------------
    1 TOTO 2
    J'espère qu'il s'agit de ce que vous cherchez.
    N'hésitez pas à re-poster si ce n'est pas (exactement) le cas.

    @++

  6. #6
    Membre chevronné Avatar de agemis31
    Profil pro
    DBA
    Inscrit en
    Octobre 2007
    Messages
    399
    Détails du profil
    Informations personnelles :
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : DBA

    Informations forums :
    Inscription : Octobre 2007
    Messages : 399
    Par défaut
    Bonjour,

    Merci elsuket pour avoir envoyé le bon lien. Le mien était un auto lien

    @+

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Avril 2009
    Messages
    24
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2009
    Messages : 24
    Par défaut
    Merci beaucoup tout fonctionne nickel maintenant et j'ai enfin réussi à faire ce que je voulais !!!!

    Merci à tous !

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

Discussions similaires

  1. [SQL] Requête pour afficher des valeurs uniques
    Par gcvoiron dans le forum PHP & Base de données
    Réponses: 4
    Dernier message: 13/11/2007, 17h38
  2. [SQL 2005] Problème pour une requête SELECT
    Par Rodie dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 23/06/2007, 17h12
  3. sql nouveau champ pour requéte
    Par tabulaire dans le forum Requêtes et SQL.
    Réponses: 2
    Dernier message: 17/08/2006, 16h16
  4. [SQL] Requête SQL trop compliquée pour lui.
    Par psychoBob dans le forum PHP & Base de données
    Réponses: 18
    Dernier message: 23/05/2006, 22h52

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