2010-06-11 99 views
5

quiero leer datos de una tabla cuyo nombre es suministrada por un usuario. Entonces, antes de comenzar realmente a leer datos, quiero verificar si la base de datos existe o no.
Comprobar si la tabla existe en C#

he visto varias piezas de código en la red que pretenden hacer esto. Sin embargo, todos parecen funcionar solo para el servidor SQL, o para mysql, o alguna otra implementación. ¿No hay una manera genérica de hacer esto?

(ya estoy separado comprobando si puedo conectar a la base de datos proporcionada, así que estoy bastante seguro de que una conexión se puede abrir la base de datos.)

+0

posible duplicado de (http://stackoverflow.com/questions/464474/check-if-a -SQL-table-existe) –

+0

@Graphain parece ser un duplicado, debería hacer algo al respecto? – apoorv020

+0

Por lo general, solo espere a que otros usuarios cierren y redireccionen, pero realmente no es un problema. –

Respuesta

2

No se puede hacer esto en una base de datos cruzada camino. En general, DDL (es decir, el código para crear tablas, índices, etc.) es completamente diferente de la base de datos a la base de datos, por lo que la lógica para verificar si existen tablas también es diferente.

Yo diría que la respuesta más simple, sin embargo, simplemente sería algo así como:

SELECT * FROM <table> WHERE 1 = 0 

Si esa consulta da un error, entonces la tabla no existe. Si funciona (aunque devolverá 0 filas), entonces la tabla existe.

tener mucho cuidado con lo que deja que la entrada del usuario, sin embargo. Lo que le impedirá especificar "sysusers" como el nombre de la tabla (en SQL Server, esa será la lista de todos los usuarios de la base de datos)

+1

¡Confiar en un error para verificar la existencia de algo parece una muy mala idea! –

+2

Por el contrario, sabemos que esta consulta no contiene errores.La única dependencia es que la tabla dada debe existir en el contexto de la conexión dada. CUALQUIER error significaría que no se puede acceder a la tabla (o algo tan extraño/aleatorio que no se puede tratar), por lo que no veo ningún problema al equiparar una excepción planteada con la falta de acceso a la tabla proporcionada. – apoorv020

+0

@Greg B: No estoy de acuerdo, diría que es un patrón muy común: ¿cómo se comprueba que exista un archivo, excepto tratando de abrirlo? ¿Cómo se verifica que un nombre de dominio sea válido, excepto tratando de resolverlo en una IP? ¿Cómo verifica que una dirección de correo electrónico sea válida, excepto al intentar enviarle un correo electrónico? Y así sucesivamente ... –

0

Eso es como preguntar "¿existe una forma genérica de obtener datos relacionados" en las bases de datos? . La respuesta es, por supuesto, no; la única "forma genérica" ​​es tener una capa de datos que oculte los detalles de implementación de su fuente de datos particular y la consulte adecuadamente.

Si realmente están apoyando y acceder a diferentes tipos de bases de datos sin un enfoque Stategy design pattern o similar, que estaría muy sorprendido.

Dicho esto, el mejor enfoque es algo así como este pedazo de código:

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; 
    } 
} 

Fuente: Check if a SQL table exists

3

Usted puede utilizar la familia de métodos DbConnection.GetSchema es posible recuperar los metadatos de la base de datos. Devolverá una DataTable con objetos de esquema. Los tipos de objetos exactos y los valores de restricción pueden variar de un proveedor a otro, pero estoy seguro de que puede configurar su cheque para una tabla específica de una manera que funcione en la mayoría de las bases de datos.

He aquí un ejemplo del uso de GetSchema que imprimirá el nombre y propietario de cada mesa que es propiedad de "nombre de esquema" y llamado "nombre de tabla". Esto se prueba contra el oráculo.

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

Cuando una tabla no existe, tanto 'OracleConnection's como' SqlConnection''s, la implementación de 'GetSchema' devolverá una DataTable con cero filas. Este resultado puede ser indistinguible de una tabla que existe, pero no tiene columnas. Sin embargo, las tablas sin columnas no están permitidas en Oracle y SQL Server. Por lo tanto, 'bool doesTableExist = (schemaDataTable.Rows.Count == 0)' debería funcionar para usted. –

0

Usted puede hacer algo como esto: [. Compruebe si existe una tabla de SQL]

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!"); 
       } 
Cuestiones relacionadas