以数据库独立的方式检查Sql数据库中是否存在表的最佳方法是什么?
我提出了:
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; }
有一个更好的方法吗?当与数据库的连接失败时,此方法将不起作用.我已经找到了Sybase,SQL服务器,Oracle的方法,但没有任何适用于所有数据库的方法.
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; } }
我不认为存在一种适用于所有数据库的通用方法,因为这是非常具体的,取决于数据库的构建方式.
但是,为什么要使用特定查询来执行此操作?难道你不能将实现抽象出你想做的事情吗?我的意思是:为什么不创建一个通用接口,其中包括一个名为'TableExists(string tablename)'的方法.然后,对于要支持的每个DBMS,创建一个实现此接口的类,并在TableExists方法中为此DBMS编写特定逻辑.
然后,SQLServer实现将包含一个查询sysobjects的查询.
在您的应用程序中,您可以拥有一个工厂类,为给定的上下文创建正确的实现,然后您只需调用TableExists方法.
例如:
IMyInterface foo = MyFactory.CreateMyInterface (SupportedDbms.SqlServer); if( foo.TableExists ("mytable") ) ...
我想我应该这样做.
如果您正在尝试数据库独立性,则必须采用最低标准.IIRC ODBC INFORMATION_SCHEMA视图是ODBC一致性所必需的,因此您可以查询它们,如:
select count (*) from information_schema.tables where table_name = 'foobar'
鉴于您使用的是ODBC,您还可以使用各种ODBC API调用来检索此元数据.
请记住,可移植性等同于任何地方的一次性写入测试,因此您仍然需要在您打算支持的每个平台上测试应用程序.这意味着您本身仅限于有限数量的可能数据库平台,因为您只有大量的测试资源.
结果是你需要为你的应用程序找到一个最小的公分母(这比查找SQL要困难得多)或构建一个平台相关的部分,其中可以在每个平台上插入非便携式功能基础.