none
Recuperer les informations d'une table RRS feed

  • Question

  • Salut à tous , je suis depuis un moment à la recherche d'un moyen de récupéré les informaations d'une table donné.

    Ce moyen doit etre generique c a d que je ne suis pas sensé savoir avec quelle base de donnée mon application va interagir.

    J'avais utilisé la methode GetShemaTable de la classe DataReader.

    Mais elle ne me donne pas les informations sur las champs etant des clé etrangère alors que j'en ai besoin.

    Et aussi , pour utiliser cette methode , il me fallait ecrire une requete (Select). Qui ne me sert à rien , ce qui n'est pas optimal.

    Pouvez vous m'aider ??
    vendredi 10 juillet 2009 10:47

Réponses

  • Bonsoir SonOfGod,

    malheureusement comme tu as pu t'en apercevoir la méthode GetSchemaTable n'est pas suffisante pour avoir une vue détaillée de la structure d'un table et de ses relations (Primary Keys, Foreign Keys, Constraints etc...).

    De la même façon, chaque SGBDR à sa propre façon d'accès a ces métadata. J'irais même plus loin, cela varie meme entre les versions d'une même moteur de base.

    Par exemple avec SQL SERVER 2005, il est possible de récupérer toutes les EXTENDED_PROPERTIES en une seule fois en se basant sur la table sys.extended_properties :
    SELECT 
        t.name AS [TABLE_NAME], 
        c.name AS [COLUMN_NAME], 
        ep.name AS [EXTENDED_NAME],
        value AS [EXTENDED_VALUE]
    FROM sys.extended_properties AS ep
    INNER JOIN sys.tables AS t ON ep.major_id = t.object_id 
    LEFT JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
    WHERE class = 1 OR class = 3
    tandis qu'avec SQL SERVER 2000 il te faudrait récupérer d'abord les propriétés étendues des tables puis celles des colonnes en passant par fn_listextendedproperty

    SELECT 
        objname AS TABLE_NAME,
        [name] AS EXTENDED_NAME,
        [value] AS EXTENDED_VALUE
    FROM ::fn_listextendedproperty (NULL, 'user', '{0}', 'TABLE', default, NULL, NULL);
    
    
    SELECT 
        objname AS COLUMN_NAME,
        [name] AS EXTENDED_NAME,
        [value] AS EXTENDED_VALUE
    FROM ::fn_listextendedproperty (NULL, 'user', '{0}', 'TABLE', '{1}', 'COLUMN', DEFAULT);
    avec ceci tu ne dispose que des propriétés étendues... rien encore sur le clefs étrangères etc...

    Pour ce faire il te faudra te baser principalement sur les vues INFORMATION_SCHEMA (que tu trouvera dans la base master).

    La requête ci-dessous, te permettra de récuperer la plupart des informations relatives aux colonnes d'une table :
    SELECT 
        TABLE_CATALOG AS [Database],
        TABLE_SCHEMA AS Owner, 
        TABLE_NAME AS TableName, 
        COLUMN_NAME AS ColumnName, 
        ORDINAL_POSITION AS OrdinalPosition, 
        COLUMN_DEFAULT AS DefaultSetting, 
        IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, 
        CHARACTER_MAXIMUM_LENGTH AS MaxLength, 
        DATETIME_PRECISION AS DatePrecision,
        COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity,
        COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed
    FROM  INFORMATION_SCHEMA.COLUMNS
    ORDER BY OrdinalPosition ASC
    Comme tu peux le constater, ce que tu cherche à faire est plutot fastidieux et la documentation plutôt rare.
    Cependant, si les termes de la licence du projet/soft sur lequel tu travaille te permettent d'utiliser des bibliothèques Open Source, je te conseillerais de t'appuyer sur les DataProviders de Subsonic 2.2 qui te fournissent exactement ce type de fonctionnalités.

    Dans tout les cas bon courage. j'espère t'avoir au moins mis sur la voie.

    Fab'
    • Marqué comme réponse SonOfGod vendredi 17 juillet 2009 11:54
    samedi 11 juillet 2009 20:47
  • Ok merci je vais essayer de voir la doc la dessus.
    Mais est ce que utiliser ces bibliotheques ne va pas rendre mon code plus lourd ? 

    En terme de modélisation, non ce ne sera pas plus lourd car ce type de librairies t'apportent justement une abstraction vis à vis du SGBDR.
    En terme de temps d'exécution, cela sera de facto plus long que si tu connaissait à l'avance la structure de ta/tes tables... malheureusement si je reprend ton premier message ce n'est pas le cas. Rien n'empêche que tu jette un œil à l'implémentation que propose telle ou telle librairie et optionnellement l'améliorer.
    es ce que je peu faire ça avec un datareader ? 

    Comme je le montrais dans ma première réponse, on récupère les informations sur une table en exécutant certaines requêtes. Le resultset qui en découle peut donc parfaitement être itéré par le biais d'un DataReader.

    Fab'
    • Proposé comme réponse Fabrice Michellonet dimanche 12 juillet 2009 12:41
    • Marqué comme réponse SonOfGod vendredi 17 juillet 2009 11:55
    dimanche 12 juillet 2009 12:41

Toutes les réponses

  • Bonsoir SonOfGod,

    malheureusement comme tu as pu t'en apercevoir la méthode GetSchemaTable n'est pas suffisante pour avoir une vue détaillée de la structure d'un table et de ses relations (Primary Keys, Foreign Keys, Constraints etc...).

    De la même façon, chaque SGBDR à sa propre façon d'accès a ces métadata. J'irais même plus loin, cela varie meme entre les versions d'une même moteur de base.

    Par exemple avec SQL SERVER 2005, il est possible de récupérer toutes les EXTENDED_PROPERTIES en une seule fois en se basant sur la table sys.extended_properties :
    SELECT 
        t.name AS [TABLE_NAME], 
        c.name AS [COLUMN_NAME], 
        ep.name AS [EXTENDED_NAME],
        value AS [EXTENDED_VALUE]
    FROM sys.extended_properties AS ep
    INNER JOIN sys.tables AS t ON ep.major_id = t.object_id 
    LEFT JOIN sys.columns AS c ON ep.major_id = c.object_id AND ep.minor_id = c.column_id
    WHERE class = 1 OR class = 3
    tandis qu'avec SQL SERVER 2000 il te faudrait récupérer d'abord les propriétés étendues des tables puis celles des colonnes en passant par fn_listextendedproperty

    SELECT 
        objname AS TABLE_NAME,
        [name] AS EXTENDED_NAME,
        [value] AS EXTENDED_VALUE
    FROM ::fn_listextendedproperty (NULL, 'user', '{0}', 'TABLE', default, NULL, NULL);
    
    
    SELECT 
        objname AS COLUMN_NAME,
        [name] AS EXTENDED_NAME,
        [value] AS EXTENDED_VALUE
    FROM ::fn_listextendedproperty (NULL, 'user', '{0}', 'TABLE', '{1}', 'COLUMN', DEFAULT);
    avec ceci tu ne dispose que des propriétés étendues... rien encore sur le clefs étrangères etc...

    Pour ce faire il te faudra te baser principalement sur les vues INFORMATION_SCHEMA (que tu trouvera dans la base master).

    La requête ci-dessous, te permettra de récuperer la plupart des informations relatives aux colonnes d'une table :
    SELECT 
        TABLE_CATALOG AS [Database],
        TABLE_SCHEMA AS Owner, 
        TABLE_NAME AS TableName, 
        COLUMN_NAME AS ColumnName, 
        ORDINAL_POSITION AS OrdinalPosition, 
        COLUMN_DEFAULT AS DefaultSetting, 
        IS_NULLABLE AS IsNullable, DATA_TYPE AS DataType, 
        CHARACTER_MAXIMUM_LENGTH AS MaxLength, 
        DATETIME_PRECISION AS DatePrecision,
        COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsIdentity') AS IsIdentity,
        COLUMNPROPERTY(object_id('[' + TABLE_SCHEMA + '].[' + TABLE_NAME + ']'), COLUMN_NAME, 'IsComputed') as IsComputed
    FROM  INFORMATION_SCHEMA.COLUMNS
    ORDER BY OrdinalPosition ASC
    Comme tu peux le constater, ce que tu cherche à faire est plutot fastidieux et la documentation plutôt rare.
    Cependant, si les termes de la licence du projet/soft sur lequel tu travaille te permettent d'utiliser des bibliothèques Open Source, je te conseillerais de t'appuyer sur les DataProviders de Subsonic 2.2 qui te fournissent exactement ce type de fonctionnalités.

    Dans tout les cas bon courage. j'espère t'avoir au moins mis sur la voie.

    Fab'
    • Marqué comme réponse SonOfGod vendredi 17 juillet 2009 11:54
    samedi 11 juillet 2009 20:47
  • merci pour ta reponse , Au juste comme je l'ai dit , je ne sais pas avec quelle Base de donné l'utilisateur de ma classe doit travailler.
    Donc l'idée de manipuler la table System de la SGBDR reste limitééé.

    samedi 11 juillet 2009 21:28
  • Oui c'est bien pour cela que je préconisais l'utilisation d'une bibliotheque comme Subsonic qui sait gérer differents SGBDR.
    Dans ce cas précis, tu aura accès à
    • SQL SERVER 2000 à 2008
    • SQL CE
    • MySQL
    • Oracle
    • SQLite
    samedi 11 juillet 2009 21:37
  • Ok merci je vais essayer de voir la doc la dessus.
    Mais est ce que utiliser ces bibliotheques ne va pas rendre mon code plus lourd ? 

    es ce que je peu faire ça avec un datareader ? 
    samedi 11 juillet 2009 22:47
  • Ok merci je vais essayer de voir la doc la dessus.
    Mais est ce que utiliser ces bibliotheques ne va pas rendre mon code plus lourd ? 

    En terme de modélisation, non ce ne sera pas plus lourd car ce type de librairies t'apportent justement une abstraction vis à vis du SGBDR.
    En terme de temps d'exécution, cela sera de facto plus long que si tu connaissait à l'avance la structure de ta/tes tables... malheureusement si je reprend ton premier message ce n'est pas le cas. Rien n'empêche que tu jette un œil à l'implémentation que propose telle ou telle librairie et optionnellement l'améliorer.
    es ce que je peu faire ça avec un datareader ? 

    Comme je le montrais dans ma première réponse, on récupère les informations sur une table en exécutant certaines requêtes. Le resultset qui en découle peut donc parfaitement être itéré par le biais d'un DataReader.

    Fab'
    • Proposé comme réponse Fabrice Michellonet dimanche 12 juillet 2009 12:41
    • Marqué comme réponse SonOfGod vendredi 17 juillet 2009 11:55
    dimanche 12 juillet 2009 12:41
  • merci
    vendredi 17 juillet 2009 11:54