2010-06-11 6 views
5

Je souhaite lire les données d'une table dont le nom est fourni par un utilisateur. Donc, avant de commencer à lire les données, je veux vérifier si la base de données existe ou non.
Vérifier si la table existe dans C#

J'ai vu plusieurs morceaux de code sur le NET qui prétendent faire cela. Cependant, ils semblent tous fonctionner uniquement pour le serveur SQL, ou pour mysql, ou une autre implémentation. N'y a-t-il pas une façon générique de le faire?

(Je suis déjà vérifiais séparement si je peux me connecter à la base de données fournie, donc je suis assez certain qu'une connexion peut être ouverte à la base de données.)

+0

double possible (http://stackoverflow.com/questions/464474/check-if-a -sql-table-exists) –

+0

@Graphain Cela semble être un doublon, devrais-je faire quelque chose? – apoorv020

+0

En général, attendez que les autres utilisateurs se referment et se redirigent, mais c'est vraiment un problème. –

Répondre

2

Vous ne pouvez pas faire cela dans une coupe base de données façon. Généralement DDL (c'est-à-dire, le code pour créer des tables, des index et ainsi de suite) est complètement différent de la base de données à la base de données et donc la logique pour vérifier si les tables existent est également différente.

Je dirais que la réponse la plus simple, cependant, serait tout simplement quelque chose comme:

SELECT * FROM <table> WHERE 1 = 0 

Si cette requête donne une erreur, la table n'existe pas. Si cela fonctionne (bien qu'il retournera 0 lignes) alors la table existe. Toutefois, faites très attention à ce que vous laissez entrer par l'utilisateur. Qu'est-ce qui l'empêche de spécifier "sysusers" comme nom de la table (dans SQL Server, ce sera la liste de tous les utilisateurs de la base de données)

+1

S'appuyer sur une erreur pour vérifier l'existence de quelque chose semble être une très mauvaise idée! –

+2

Au contraire, nous savons que cette requête ne contient aucune erreur.La seule dépendance est que la table donnée doit exister dans le contexte de la connexion donnée. TOUTE erreur signifierait que la table ne peut pas être accédée (ou quelque chose de si bizarre/aléatoire qui ne peut pas être traité), ainsi je ne vois aucun problème en assimilant une exception augmentée avec le manque d'accès à la table supllied. – apoorv020

+0

@Greg B: Je ne suis pas d'accord, je dirais que c'est un modèle très commun: comment vérifier un fichier existe, sauf en essayant de l'ouvrir? Comment vérifier qu'un nom de domaine est valide, sauf en essayant de le résoudre en IP? Comment vérifiez-vous qu'une adresse e-mail est valide, sauf en essayant d'envoyer un e-mail? Et ainsi de suite ... –

0

C'est comme demander "existe-t-il un moyen générique d'obtenir des données connexes" dans les bases de données? . La réponse est bien sûr non - la seule "manière générique" est d'avoir une couche de données qui cache les détails d'implémentation de votre source de données particulière et l'interroge de manière appropriée.

Si vous soutenez réellement et accédez à différents types de bases de données sans Stategy design pattern ou une approche similaire, je serais très surpris.

Cela étant dit, la meilleure approche est quelque chose comme ce morceau de code:

bool exists; 

try 
{ 
    // ANSI SQL way. Works in PostgreSQL, MSSQL, MySQL. 
    var cmd = new OdbcCommand(
     "select case when exists((select * from information_schema.tables where table_name = '" + tableName + "')) then 1 else 0 end"); 

    exists = (int)cmd.ExecuteScalar() == 1; 
} 
catch 
{ 
    try 
    { 
     // Other RDBMS. Graceful degradation 
     exists = true; 
     var cmdOthers = new OdbcCommand("select 1 from " + tableName + " where 1 = 0"); 
     cmdOthers.ExecuteNonQuery(); 
    } 
    catch 
    { 
     exists = false; 
    } 
} 

Source: Check if a SQL table exists

3

Vous pouvez utiliser la famille DbConnection.GetSchema des méthodes pour récupérer des métadonnées sur la base de données. Il retournera un DataTable avec des objets de schéma. Les types d'objets exacts et les valeurs de restriction peuvent varier d'un fournisseur à l'autre, mais je suis sûr que vous pouvez configurer votre vérification pour une table spécifique d'une manière qui fonctionnera dans la plupart des bases de données. Voici un exemple d'utilisation de GetSchema qui affichera le nom et le propriétaire de chaque table appartenant à "nom de schéma" et appelée "nom de table". Ceci est testé contre Oracle.

static void Main(string[] args) 
{ 
    string providerName = @"System.Data.OracleClient"; 
    string connectionString = @"..."; 

    DbProviderFactory factory = DbProviderFactories.GetFactory(providerName); 
    using (DbConnection connection = factory.CreateConnection()) 
    { 
     connection.ConnectionString = connectionString; 
     connection.Open(); 
     DataTable schemaDataTable = connection.GetSchema("Tables", new string[] { "schema name", "table name" }); 
     foreach (DataColumn column in schemaDataTable.Columns) 
     { 
      Console.Write(column.ColumnName + "\t"); 
     } 
     Console.WriteLine(); 
     foreach (DataRow row in schemaDataTable.Rows) 
     { 
      foreach (object value in row.ItemArray) 
      { 
       Console.Write(value.ToString() + "\t"); 
      } 
      Console.WriteLine(); 
     } 
    } 
} 
+0

Lorsqu'une table n'existe pas, à la fois 'OracleConnection' et' SqlConnection', l'implémentation de 'GetSchema' retournera un DataTable avec zéro lignes. Ce résultat peut être indiscernable d'une table qui existe, mais n'a pas de colonnes. Toutefois, les tables sans colonnes ne sont pas autorisées dans Oracle et SQL Server. Donc, 'bool doesTableExist = (schemaDataTable.Rows.Count == 0)' devrait fonctionner pour vous. –

0

Vous pouvez faire quelque chose comme ceci: [. Vérifiez si une table SQL existe]

string strCheck = "SHOW TABLES LIKE \'tableName\'"; 
       cmd = new MySqlCommand(strCheck, connection); 
       if (connection.State == ConnectionState.Closed) 
       { 
        connection.Open(); 
       } 
       cmd.Prepare(); 
       var reader = cmd.ExecuteReader(); 
       if (reader.HasRows) 
       {        
        Console.WriteLine("Table Exist!"); 
       } 
       else (reader.HasRows) 
       {        
        Console.WriteLine("Table Exist!"); 
       } 
Questions connexes