Meilleur auteur de réponses
Recuperer les informations d'une table

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 ??
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
-
Ok merci je vais essayer de voir la doc la dessus.
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.Mais est ce que utiliser ces bibliotheques ne va pas rendre mon code plus lourd ?
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
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
-
-
-
-
Ok merci je vais essayer de voir la doc la dessus.
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.Mais est ce que utiliser ces bibliotheques ne va pas rendre mon code plus lourd ?
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
-