2010-10-15 20 views
2

Je dois obtenir les noms de colonne, les clés primaires, les clés étrangères et d'autres informations de schéma. La classe DataTable semble contenir tous ces éléments.Récupérer des informations DataTable pour une table dans SQL Server

Vous trouverez ci-dessous le code actuel. Avec cela, je pourrais récupérer toutes les informations sauf les clés étrangères . Je m'attends à ce qu'ils soient définis dans DataTable.Constraints mais ils ne le sont pas. Ceci est mon code actuel:

private static DataTable LoadSchemaInfo(string tableName, SqlConnection connection) 
    { 
     string cmdText = "SELECT * FROM [" + tableName + "] WHERE 1 = 0"; 

     // Create a SqlDataAdapter to get the results as DataTable 
     var sqlDataAdapter = new SqlDataAdapter(cmdText, connection); 

     // Create a new DataTable 
     var dataTable = new DataTable(tableName); 

     // Fill the DataTable with the result of the SQL statement 
     sqlDataAdapter.FillSchema(dataTable, SchemaType.Source); 

     return dataTable; 
    } 

Toute idée comment récupérer toute information ou comment obtenir le FK (de préférence sans utiliser la syntaxe SQL pur parce que je puis le manque d'une vérification de la compilation)?

Répondre

5

En utilisant SMO vous pouvez le faire ...

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Data.SqlClient; 
using Microsoft.SqlServer.Management.Smo; 
using Microsoft.SqlServer.Management.Smo.Agent; 


// Add references: (in c:\Program Files\Microsoft SQL Server\90\SDK\Assemblies\) 
// Microsoft SqlServer.ConnectionInfo 
// Microsoft SqlServer.Management.Sdk.Sfc 
// Microsoft SqlServer.Smo 

namespace SMO 
{ 
    class Program 
    { 
     static Database db; 

     static void Main(string[] args) 
     { 
      Microsoft.SqlServer.Management.Smo.Server server; 

      SqlConnection sqlConnection = new SqlConnection(@"Integrated Security=SSPI; Data Source=LOCAL"); 
      //build a "serverConnection" with the information of the "sqlConnection" 
      Microsoft.SqlServer.Management.Common.ServerConnection serverConnection = 
       new Microsoft.SqlServer.Management.Common.ServerConnection(sqlConnection); 

      //The "serverConnection is used in the ctor of the Server. 
      server = new Server(serverConnection); 

      db = server.Databases["TestDB"]; 

      Table tbl; 
      tbl = db.Tables["Sales"]; 
      foreach (ForeignKey fk in tbl.ForeignKeys) 
      { 
       Console.WriteLine("Foreign key {0} references table {1} and key {2}", fk.Name, fk.ReferencedTable, fk.ReferencedKey); 
      } 
     } 
    } 
} 
+1

Nice. Toute version de ce code utilisant un 'SqlConnection'? J'espère que la référence externe ne sera pas un problème. – Wernight

+2

Cela devrait fonctionner: nouveau serveur (new ServerConnection (sqlConnection)). – VladV

+0

Je trouve cela très utile merci :) – daehaai

0

Si vous recherchez les contraintes du schéma de votre base de données, un DataTable ADO.net n'est pas votre meilleure option. Vous pouvez trouver en utilisant SMO une option plus appropriée.

1

Vous pouvez toujours vérifier les dans votre base de données vues de catalogue sys, en utilisant une simple requête ADO.NET - vues comme:

  • sys.columns avec des informations sur vos colonnes
  • sys.foreign_keys qui stocke des informations sur les clés étrangères
  • sys.tables pour les tables

etc. et ainsi de suite. Faites juste un SELECT (list of fields) FROM sys.foreign_keys et voyez ce que vous obtenez!

Voir: Livres en ligne Querying the SQL Server System Catalog pour plus de détails.

+0

Franchement horrible à utiliser. Pas OO et renvoie l'ID des tables lorsque j'ai besoin de noms de tables. – Wernight

+1

Horrible - c'est à discuter. Mais efficace !! Aussi: utilisez simplement OBJECT_NAME (object_id) 'et vous avez votre nom de table .... aussi: SQL Server est un SGBDR - pas un système OO ..... –

+0

Merci pour cet OBJECT_NAME, c'est très utile. – Wernight

0

Vous pouvez utiliser SqlConnection pour obtenir les informations.

string connectionString = "Data Source=.;Initial Catalog=Northwind;Integrated Security=True"; 
using (SqlConnection conn = new SqlConnection(connectionString)) 
{ 
    conn.Open(); 

    DataTable dtAllForeignKeys = conn.GetSchema("ForeignKeys"); 

    string[] restrictionValues = { "Northwind", "dbo", "Orders" }; 
    DataTable dtForeignKeysForJustTheOrderTable = conn.GetSchema("ForeignKeys", restrictionValues); 
    conn.Close(); 
} 
+0

Il semble ne pas contenir directement le nom de la table référencée. Seul le nom de la contrainte FK. – Wernight

+0

http://blog.sqlauthority.com/2006/11/01/sql-server-query-to-display-key-key-relationships-and-name-of-the-constraint-for-each-table-in -base de données/ –

0

L'objet DataTable n'est pas identique à la table de base de données. Ils ont juste la même structure à cause de la façon dont vous les créez. Par exemple, vous pouvez avoir un DataTable qui contient le résultat d'une jointure entre plusieurs tables de base de données. Un DataTable peut avoir une clé étrangère à un autre DataTable, mais pas à une table de base de données. Pour obtenir des informations sur les clés étrangères dans la base de données, vous devez lire les métadonnées des tables (lorsque vous appelez SELECT, vous obtenez uniquement des métadonnées pour la requête, c'est pourquoi vous n'obtenez aucune information sur les clés).
Vous pouvez interroger ces informations directement à partir de Information Schema Views ou demander aux classes SMO de le faire pour vous. Dans ce dernier cas, vous commencez par l'objet Server, puis obtenez Database, Tables et ainsi de suite.