2013-06-26 81 views
4

我一直在使用VBA来检查我的Access 2000数据库中的所有查询,窗体和模块,但它可能非常繁琐和缓慢。最近,我决定仔细研究Access中的系统表,特别是MSysQueries和MSysObjects。我可以使用这些表来更快地检查数据库中的对象吗?当然,这些表是只读的,所以我无法通过它们修改数据库而无需返回到VBA。 MSysQueries中的属性是什么意思?MSysQueries中的数据是什么意思?

回答

9

那么,我在Google组上遇到了this post。我在自己的桌子上进行了进一步的调查,并希望分享一份我已经完成的工作所激发的信息表格。

每个查询可占据表中的多行。

属性为0的行是查询的开始。

属性为1的行表示查询的类型。

  • 标志值1 = SELECT查询。
  • 标志值2 = SELECT ... INTO查询或make表查询。 Name1将具有创建的表的名称。
  • 标志值3 = INSERT查询; Name1将具有要插入的表的名称。
  • 标志值4 = UPDATE查询
  • 标志值5 = DELETE查询
  • 标志值6 =交叉表查询(变换)
  • 标志值9 = UNION查询

的与属性2行(可能有多个)是查询的每个形式参数。标志列指示数据类型(即,对于dbText为“10”),并且Name1列指示参数的名称。如果没有属性2的行,那么查询没有形式参数。

属性为3的行表示存在UNION或DISTINCT关键字。

  • 标志值0 =没有什么特别
  • 标志值1 = UNION ALL
  • 标志值2 = SELECT DISTINCT
  • 标志值3 = UNION
  • 标志值8 = SELECT DISTINCTROW
  • 标志值9 =对主字段和子字段的查询

与attribu te 4表示查询是否来自外部数据库。如果属性4存在,Name1将包含源代码。

属性为5的行(可能有多个)表示在查询中找到的每个表。如果查询是UNION查询,则表达式字段在UNION关键字上具有拆分,并且Name2字段具有系统生成的表别名。对于查询中的所有其他表,Name1是表的名称,Name2是别名(如果有的话)。

属性6(可能有多个)的行表示查询中的每个单个字段或表达式。如果查询没有属性6,则假定的行为是包含所有字段。 “表达式”字段包含每个字段表达式或名称,而“名称1”包含字段别名(如果有)。

  • 标志值0的字段或表达
  • 标志值1 =值=该字段是在交叉表查询中的列标题。
  • 标志值2 =该字段是交叉表查询中的行标题。

具有属性7(可能有多个)的行表示每个单个联接“ON”表达式。表达式字段包含实际的连接表达式。 Name1包含连接中的第一个表。 Name2包含连接中的第二个表。

  • 标志值1 =内部联接
  • 标志值2 =左加入
  • 标志值3 =右加入

与属性8的行中包含整个WHERE在表达式字段子句。如果没有where子句,则从查询中省略属性8。

属性9(可能有多个)的行表示查询的GROUP BY子句中的每个单独的Group By表达式。表达式字段包含每个表达式的组。

  • 标志值0的字段或表达
  • 标志值1 =值=该字段是在交叉表查询中的列标题。
  • 标志值2 =该字段是交叉表查询中的行标题。

具有属性11(可能有多个)的行表示查询的ORDER BY子句中的每个Order by表达式。表达式字段包含每个表达式的顺序。 Name1有“D”或“d”表示排序按降序完成。

属性为255的行是查询的结尾。

我不完全确定Order字段是干什么的,但我确实发现它不是Null,尽管它有时是空字符串的值,但并不总是具有该值。空字符串出现在属性5,6,7和9上,但它们并不总是这些属性的空字符串。

+0

绝妙的回答。谢谢 ! –

+0

Attribute = 1,Flag = 8表示通过查询,Name1返回Connect String –

+0

FYI:http://stackoverflow.com/q/25199627/78522 –

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视图中创建一个查询并粘贴上面的代码即可。

1

继Bobort和iDevlop的答案:

行与属性1指示查询的类型。

  • 标志值7 = DDL查询(例如CREATE TABLE...
  • 标志值= 9通过查询

行传递与属性3表示谓词。

  • 标志值1 =所有的值,或UNION ALL(如果UNION查询)
  • 标志值4 = WITH OWNERACCESS OPTION
  • 标志值16 = TOP N
  • 标志值48 = TOP N PERCENT

与属性5所述的行(可能有多个)指示在查询中找到的每个FROM表/查询

  • 表达式中包含FROM来源,或SELECT语句,如果UNION查询

行与属性10包含整个HAVING Expression域条款。如果没有HAVING子句,则从查询中省略属性10。

Order字段是包含4字节数组的BIG-ENDIAN二进制值(可以使用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