使用 OleDB 列出所有存储过程和查询时出现不明确的外部连接错误
Posted
技术标签:
【中文标题】使用 OleDB 列出所有存储过程和查询时出现不明确的外部连接错误【英文标题】:Ambiguous Outer Join Error While Using OleDB to List all Stored Procedures and Queries 【发布时间】:2012-07-31 22:01:18 【问题描述】:我必须记录几个 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 FROM MsysObjects WHERE (Left$([Name],1)"~") AND (MSysObjects.Type)=5 按 MSysObjects.Name 排序
或
SELECT Name FROM MSysObjects WHERE (Name Not Like ""MSys*"") AND (Type In (1,4,6)) ORDER BY Name
同样,两个字符串也会引发相同的“Ambiguous Outer Join”错误。
我已经阅读了一些有关此类错误的信息,并且我知道一般建议是将原始查询分解为多个查询,但是由于我使用库函数来获取此架构数据,所以我不是确定如何去做。我已经花了几天时间研究这个,但我无能为力。如果有人可以帮助我解决这个问题或指出我绕过这个障碍的方法,我将不胜感激。
【问题讨论】:
这没什么帮助,但我尝试了你的代码模型,它对我有用。 @Remou 在某种程度上确实有帮助,谢谢。大多数其他人报告说'db.GetOleDbSchemaTable(OleDbSchemaGuid.Procedures,objArrRestrict);'应该在我使用它时工作。我使用 VBA 重写了相同的代码,但仍然出现“不明确的外部连接”错误。我开始认为数据库本身有问题。另外,我想知道是否有某种方法可以解决这个问题,因为我可以在 OleDbSchemaGuid.Procedures 上调用 GetOleDbSchemaTable() 之前获取所有存储的视图(SELECT 查询)以某种方式过滤掉它们。跨度> 另外,需要明确的是,OleDbSchemaGuid.Procedures 是目前在 OleDB 中给我带来问题的唯一过滤器。其他人工作得很好。谢谢! 您是否尝试过处理通常损坏的数据库例程:压缩和修复、反编译等 (granite.ab.ca/access/corruptmdbs.htm)?我会警惕在 Access 之外使用系统表,存在难以解决的权限问题。 我很早就遇到了这些权限问题,但我早就修复了它们。现在我只是想处理这个总是在 GetSchemaTable 行中断的神秘的“Ambiguous Outer Join”错误。我可能可以手动完成所有这些操作,但是表和查询太多了,您可以想象我是多么绝望地试图避免手动执行所有列跟踪。 【参考方案1】:如果你这样分组会发生什么?
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
【讨论】:
注意我认为 Like 应该是 'value' 而不是引号/双引号。 问题不在于我的查询不是格式良好的语句。在那种情况下,我会收到完全不同的错误消息。我只是使用双引号作为 C# 特定的东西。如果我按照您的建议更改查询,我仍然会收到一条不明确的外部联接错误消息。以上是关于使用 OleDB 列出所有存储过程和查询时出现不明确的外部连接错误的主要内容,如果未能解决你的问题,请参考以下文章
如何在 C# 中使用 OleDB 列出 MS Access 文件中的所有查询?
ORACLE PL/SQL 在查询 3 列信息时出现存储过程错误