我一直在使用VBA来检查我的Access 2000数据库中的所有查询,表单和模块,但它可能非常繁琐和缓慢。最近,我决定仔细研究Access中的系统表,特别是MSysQueries和MSysObjects。我可以使用这些表来更快地检查数据库中的对象吗?当然,这些表是只读的,所以我不能通过它们对数据库进行任何修改而不返回VBA。 MSysQueries中的属性是什么意思?
答案 0 :(得分:11)
好吧,我在Google群组中遇到了this post。我在自己的桌子上做了进一步的调查,想要分享一个我已经完成的工作所创造的信息表。
每个查询都可以占用表格中的多行。
属性为0的行是查询的开头。
具有属性1的行表示查询的类型。
具有属性2的行(可能有多个)是查询的每个形式参数。 Flag列表示数据类型(即dbText的“10”),Name1列表示参数的名称。如果没有属性为2的行,则查询没有形式参数。
属性为3的行表示存在UNION或DISTINCT关键字。
具有属性4的行指示查询是否来自外部数据库。如果属性4存在,Name1将包含源。
具有属性5的行(可能有多个)表示查询中找到的每个表。如果查询是UNION查询,则Expression字段对UNION关键字进行拆分,Name2字段具有系统生成的表别名。对于查询中的所有其他表,Name1是表的名称,Name2是别名(如果有)。
具有属性6的行(可能有多个)表示查询中的每个单个字段或表达式。如果查询没有属性6,则假定的行为是包含所有字段。 Expression字段包含每个字段表达式或名称,Name1包含字段别名(如果有)。
具有属性7的行(可能有多个)表示每个单独的连接“ON”表达式。 Expression字段包含实际的连接表达式。 Name1包含连接中的第一个表。 Name2包含连接中的第二个表。
具有属性8的行包含Expression字段中的整个WHERE子句。如果没有where子句,则从查询中省略属性8.
具有属性9的行(可能有多个)表示查询的GROUP BY子句中的每个Group By表达式。 “表达式”字段按表达式包含每个组。
具有属性11的行(可能有多个)表示查询的ORDER BY子句中的每个单个Order By表达式。表达式字段按表达式包含每个顺序。 Name1有“D”或“d”表示排序是按降序完成的。
具有属性255的行是查询的结尾。
我不确定Order字段的作用,但我确实发现它不是Null,虽然它有时会有一个空字符串的值,但它并不总是具有该值。空字符串出现在属性5,6,7和9上,但对于这些属性,它并不总是空字符串。
答案 1 :(得分:3)
感谢@Bobort的精彩解释,我能够创建一个查询,列出当前数据库中的所有查询,包括输入表/查询,查询类型和目标表(用于操作查询)。 我想我可以在这里分享一下。
SELECT MSysObjects.Name AS queryName,
Mid("SelectMakTblAppendUpdateDeleteXtab 777777PassThUnion ",([msysqueries]![Flag]-1)*6+1,6) AS queryType,
src.Name1 AS [Input],
MSysQueries.Name1 AS Target
FROM (MSysQueries INNER JOIN MSysObjects ON MSysQueries.ObjectId = MSysObjects.Id)
LEFT JOIN (select * from MSysQueries WHERE Attribute = 5 ) AS src
ON MSysQueries.ObjectId = src.ObjectId
WHERE (((MSysObjects.Name)>"~z") AND ((MSysQueries.Attribute) =1))
ORDER BY MSysObjects.Name, src.Name1;
要使用,只需在SQL视图中创建一个查询并粘贴上面的代码。
答案 2 :(得分:2)
继Bobort和iDevlop的答案之后:
具有属性1的行表示查询的类型。
CREATE TABLE...
)具有属性3的行表示谓词。
属性为5的行(可能有多个)表示查询中找到的每个 FROM 表/查询
具有属性10的行包含Expression字段中的整个HAVING子句。如果没有HAVING子句,则查询中将省略属性10.
Order
字段是BIG-ENDIAN二进制值,包含4个字节的数组(二进制字段可以添加VBA,但不能使用UI添加,除非您从二进制字段复制和粘贴在系统表中。)但是,在大多数数据库中,在MSysQueries
表中,您不太可能遇到大于255的二进制值,因此您可以通过检查索引处的字节来快速转换为字节3.例如:
Sub EnumOrder()
Dim rst As Recordset
Set rst = CurrentDb.OpenRecordset( _
" SELECT * FROM MSysQueries " & _
" WHERE Attribute = 6 " & _
"ORDER BY ObjectId Asc, [Order] Asc")
With rst
Do While Not .EOF
Debug.Print .Fields("ObjectId"), .Fields("Order")(3)
.MoveNext
Loop
.Close
End With
End Sub
答案 3 :(得分:1)
属性3出现累积值。因此,其他项目包括:
我写了一篇有关MSysQueries表工作原理的扩展文章。参见How Access stores queries。