我必须记录几个 MS Access 2007 数据库,每个数据库都有数百个宏查询等,我想在 C# 中自动化这个过程。对于每个 .mdb 文件,我的首要目标是提取模式信息(表、表单、宏以及查询名称和定义)。
我正在使用以下代码使用 OleDB 来获取用户所有可用表的列表:
private static List<String> getTableNames(OleDbConnection db)
{
List<String> tableList = new List<String>();
DataTable schemaTable;
try
{
object[] objArrRestrict = new object[] { null, null, null, "TABLE" };
schemaTable = db.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,objArrRestrict);
foreach(DataRow row in schemaTable.Rows) tableList.Add((String)row["TABLE_NAME"]);
}
catch(Exception e) {
Console.WriteLine(`"Table Name Querying Failed. Returning Empty List"`);
Console.WriteLine(e.Message);
}
return tableList;
}
对于列,我使用了类似的方法,只是像这样从前一个中提取:
object[] objArrRestrict = new object[] { null, null, tableName, null };
schemaCols = db.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, objArrRestrict);
foreach (DataRow row in schemaCols.Rows) tableList.Add((String)row["COLUMN_NAME"]);
我不太确定如何获取宏信息(名称和定义),但经过一番研究,我决定使用以下内容来获取查询信息。
object[] objArrRestrict = new object[] { null, null, null, null };
schemaCols = db.GetOleDbSchemaTable(OleDbSchemaGuid.Procedures, objArrRestrict);
但是,当我运行最后一段代码时,我收到了措辞含糊的错误消息:
The SQL statement could not be executed because it contains ambiguous outer joins. To force one of the joins to be performed first, create a separate query in your SQL statement.
经过更多研究后,我修改了 getTableNames 方法以通过“VIEWS”限制获取查询,但这仅在数据库中获取了存储的 SELECT 查询,而且我还需要存储的 INSERT、UPDATE 和 DELETE 查询。
最后,我现在使用下面的代码直接查询 MsysObjects 表。
String cmdString;
OleDbCommand queries = new OleDbCommand(cmdString,db);
OleDbDataReader reader = queries.ExecuteReader();
交替使用以下两个 cmdString:
SELECT MSysObjects.Name 从 MsysObjects WHERE (Left$([Name],1)<>"~") AND (MSysObjects.Type)=5 ORDER BY MSysObjects.Name
或者
SELECT Name FROM MSysObjects WHERE (Name Not Like ""MSys*"") AND (Type In (1,4,6)) ORDER BY Name
同样,两个字符串也会引发相同的“Ambiguous Outer Join”错误。
我已经阅读了一些有关此类错误的信息,并且我知道一般建议是将原始查询分解为多个查询,但是由于我正在使用库函数来获取此模式数据,因此我不确定如何准确去做那件事。我已经花了几天时间研究这个,但我无能为力。如果有人可以帮助我解决这个问题或指出我绕过这个障碍的方法,我将不胜感激。