1

我必须记录几个 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”错误。

我已经阅读了一些有关此类错误的信息,并且我知道一般建议是将原始查询分解为多个查询,但是由于我正在使用库函数来获取此模式数据,因此我不确定如何准确去做那件事。我已经花了几天时间研究这个,但我无能为力。如果有人可以帮助我解决这个问题或指出我绕过这个障碍的方法,我将不胜感激。

4

1 回答 1

0

如果你这样分组会发生什么?

SELECT 
Name 
FROM 
MSysObjects 
WHERE 
Name Not Like 'MSys*'
AND 
Type In (1,4,6)
ORDER BY Name

或者这个

SELECT 
Name 
FROM 
MSysObjects 
WHERE 
(
(Name Not Like ""MSys*"") 
AND 
(Type In (1,4,6))
)
ORDER BY Name
于 2012-08-01T01:41:39.823 回答