我想从名称由用户提供的表中读取数据。所以在实际开始读取数据之前,我想检查数据库是否存在。
我已经在NET上看到了几条声称可以执行此操作的代码。但是,它们似乎只适用于SQL服务器,或mysql或其他一些实现。有没有通用的方法来做到这一点?
(我已经单独检查是否可以连接到提供的数据库,所以我非常确定可以打开到数据库的连接。)
答案 0 :(得分:3)
您不能以跨数据库的方式执行此操作。通常,DDL(即创建表,索引等的代码)与数据库完全不同,因此检查表是否存在的逻辑也不同。
我想说最简单的答案就是:
SELECT * FROM <table> WHERE 1 = 0
如果该查询出错,则该表不存在。如果它工作(虽然它将返回0行),那么表存在。
但是要非常小心你让用户输入的内容。什么阻止他指定“sysusers”作为表名(在SQL Server中,这将是所有数据库用户的列表)
答案 1 :(得分:3)
您可以使用DbConnection.GetSchema系列方法来检索有关数据库的元数据。它将返回带有架构对象的DataTable。确切的对象类型和限制值可能因供应商而异,但我确信您可以以适用于大多数数据库的方式设置对特定表的检查。
以下是使用GetSchema的示例,该示例将打印由“架构名称”拥有并称为“表名”的每个表的名称和所有者。这是针对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();
}
}
}
答案 2 :(得分:0)
这就像在数据库中询问“是否存在获取相关数据的通用方法”。答案当然是否定的 - 唯一的“通用方法”是拥有一个数据层来隐藏特定数据源的实现细节并对其进行适当的查询。
如果你真的支持和访问许多不同类型的数据库而没有Stategy design pattern或类似的方法,我会非常惊讶。
话虽如此,最好的方法就是这样的代码:
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;
}
}
答案 3 :(得分:0)
您可以这样做:
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!");
}