MSysQueries中的数据是什么意思?

时间:2013-06-26 19:52:27

标签: ms-access ms-access-2000

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

4 个答案:

答案 0 :(得分:11)

好吧,我在Google群组中遇到了this post。我在自己的桌子上做了进一步的调查,想要分享一个我已经完成的工作所创造的信息表。

每个查询都可以占用表格中的多行。

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

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

  • 标记值1 = SELECT查询。
  • 标记值2 = SELECT ... INTO查询或生成表查询。 Name1将具有创建的表的名称。
  • 标志值3 = INSERT查询; Name1将具有要插入的表的名称。
  • 标记值4 =更新查询
  • 标记值5 = DELETE query
  • 标记值6 =交叉表查询(TRANSFORM)
  • 标记值9 = UNION查询

具有属性2的行(可能有多个)是查询的每个形式参数。 Flag列表示数据类型(即dbText的“10”),Name1列表示参数的名称。如果没有属性为2的行,则查询没有形式参数。

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

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

具有属性4的行指示查询是否来自外部数据库。如果属性4存在,Name1将包含源。

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

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

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

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

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

具有属性8的行包含Expression字段中的整个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上,但对于这些属性,它并不总是空字符串。

答案 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的行表示查询的类型。

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

具有属性3的行表示谓词。

  • 标记值1 =所有值,或UNION ALL(如果是UNION查询)
  • 标志值4 =使用OWNERACCESS选项
  • 标志值16 = TOP N
  • 标志值48 = TOP N PERCENT

属性为5的行(可能有多个)表示查询中找到的每个 FROM 表/查询

  • Expression包含FROM源,如果是UNION查询,则包含SELECT语句

具有属性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出现累积值。因此,其他项目包括:

  • 标记12选择区域...。具有所有权选项
  • 标志18 SELECT DISTINCT TOP(即2 + 16)
  • 标志24 SELECT DISTINCTROW TOP(即8 + 16)
  • 标记50 SELECT DISTINCT TOP PERCENT(即2 + 48)
  • 标志56选择DISTINCTROW TOP百分比(即8 + 48)

我写了一篇有关MSysQueries表工作原理的扩展文章。参见How Access stores queries