vacia - validar usuario existente c#
Compruebe si existe una tabla SQL (9)
¿Cuál es la mejor manera de verificar si una tabla existe en una base de datos Sql en una base de datos de manera independiente?
Se me ocurrio:
bool exists;
const string sqlStatement = @"SELECT COUNT(*) FROM my_table";
try
{
using (OdbcCommand cmd = new OdbcCommand(sqlStatement, myOdbcConnection))
{
cmd.ExecuteScalar();
exists = true;
}
}
catch
{
exists = false;
}
¿Hay una mejor manera de hacer esto? Este método no funcionará cuando la conexión a la base de datos falla. He encontrado formas para Sybase, SQL server, Oracle pero nada que funcione para todas las bases de datos.
Apoyo totalmente la respuesta de Frederik Gheysels. Si tiene que admitir múltiples sistemas de bases de datos, debe implementar su código contra una interfaz abstracta con implementaciones específicas por sistema de base de datos. Hay muchos más ejemplos de sintaxis incompatible que simplemente verificar una tabla existente (por ejemplo, limitar la consulta a un cierto número de filas).
Pero si realmente tiene que realizar el control utilizando el manejo de excepciones de su ejemplo, debe usar la siguiente consulta que es más eficiente que un COUNT (*) porque la base de datos no tiene trabajo de selección real que hacer:
SELECT 1 FROM my_table WHERE 1=2
En el proyecto actual en mi trabajo, necesito escribir ''agente de datos'', que sería compatible con muchos tipos de bases de datos.
Así que decidí hacer lo siguiente: escribir una clase base con la funcionalidad base (independiente de la base de datos) usando métodos virtuales y anular en subclases todos los momentos específicos de la base de datos.
No creo que exista una forma genérica que funcione para todas las Bases de datos, ya que esto es algo muy específico que depende de cómo se construya la base de datos.
Pero, ¿por qué quieres hacer esto usando una consulta específica? ¿No puedes abstraer la implementación de lo que quieres hacer? Quiero decir: ¿por qué no crear una interfaz genérica, que tiene, entre otros, un método llamado ''TableExists (string tablename)'' por ejemplo. Luego, para cada DBMS que quiera admitir, crea una clase que implementa esta interfaz, y en el método TableExists, escribe lógica específica para este DBMS.
La implementación de SQLServer contendrá una consulta que consulta sysobjects.
En su aplicación, puede tener una clase de fábrica que crea la implementación correcta para un contexto dado, y luego simplemente llama al método TableExists.
Por ejemplo:
IMyInterface foo = MyFactory.CreateMyInterface (SupportedDbms.SqlServer);
if( foo.TableExists ("mytable") )
...
Creo que así es como debería hacerlo.
Si intenta independizar la base de datos, deberá asumir un estándar mínimo. IIRC Las vistas ANSI INFORMATION_SCHEMA son obligatorias para la conformidad con ODBC, por lo que puede consultarlas como:
select count (*)
from information_schema.tables
where table_name = ''foobar''
Dado que está utilizando ODBC, también puede usar varias llamadas a API ODBC para recuperar estos metadatos también.
Tenga en cuenta que la portabilidad equivale a una prueba de escritura única en cualquier lugar por lo que todavía tendrá que probar la aplicación en cada plataforma que pretenda admitir. Esto significa que está intrínsecamente limitado a un número finito de plataformas de bases de datos posibles ya que solo tiene tantos recursos para probar.
El resultado es que necesita encontrar un mínimo común denominador para su aplicación (que es bastante más difícil de lo que parece para SQL) o crear una sección dependiente de la plataforma donde las funciones no portátiles se pueden conectar en una plataforma por plataforma base.
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;
}
}
Evitaría ejecutar el select count(x) from xxxxxx
ya que el DBMS continuará y lo hará, lo que puede llevar un tiempo para una tabla grande.
En su lugar, solo prepare una select * from mysterytable
consulta de select * from mysterytable
. La preparación fallará si no existe una tabla misteriosa. No es necesario ejecutar realmente la declaración preparada.
Lo siguiente me funciona bien ...
private bool TableExists(SqlConnection conn, string database, string name)
{
string strCmd = null;
SqlCommand sqlCmd = null;
try
{
strCmd = "select case when exists((select ''[''+SCHEMA_NAME(schema_id)+''].[''+name+'']'' As name FROM [" + database + "].sys.tables WHERE name = ''" + name + "'')) then 1 else 0 end";
sqlCmd = new SqlCommand(strCmd, conn);
return (int)sqlCmd.ExecuteScalar() == 1;
}
catch { return false; }
}
Si quiere evitar las soluciones try-catch, sugiero este método, usando sys.tables
private bool IsTableExisting(string table)
{
string command = $"select * from sys.tables";
using (SqlConnection con = new SqlConnection(Constr))
using (SqlCommand com = new SqlCommand(command, con))
{
SqlDataReader reader = com.ExecuteReader();
while (reader.Read())
{
if (reader.GetString(0).ToLower() == table.ToLower())
return true;
}
reader.Close();
}
return false;
}
Muy simple
use YOUR_DATABASE --OPTIONAL
SELECT count(*) as Exist from INFORMATION_SCHEMA.TABLES where table_name = ''YOUR_TABLE_NAME''
Si la respuesta es 1, hay una tabla. Si la respuesta es 0, no hay tabla.