【问题标题】:Record cannot be read; no read permission on 'MSysObjects'无法读取记录; 'MSysObjects' 没有读取权限
【发布时间】:2010-12-28 14:31:33
【问题描述】:

我正在尝试使用 Excel VBA 从 Access 2007 ACCDB 格式数据库中获取所有表的列表。

我关注了这个帖子:

How can I get table names from an MS Access Database?

使用:

SELECT MSysObjects.Name AS table_name
FROM MSysObjects
WHERE
        (((Left([Name],1))<>"~")
    AND ((Left([Name],4))<>"MSys")
    AND ((MSysObjects.Type) In (1,4,6)))
order by MSysObjects.Name

但我收到此错误。

无法读取记录; 'MSysObjects' 没有读取权限

我希望能够仅使用 SQL 语句而不是 OpenSchema 方法来获取表名。

我认为问题出在 Access 上。我不确定。

有人知道吗?

【问题讨论】:

  • 你的编程环境是什么?您打算将结果用于什么目的?
  • 另外,您的文件格式是什么 - ACCDB 或 MDB?
  • 感谢您的提问。我正在使用 ACCDB。
  • 另外,我正在使用 VBA 将信息从 Access 传输到 Excel。
  • 您的 VBA 是在 Excel 中还是在 Access 中?

标签: excel ms-access ms-access-2007 vba


【解决方案1】:

由于您的数据库是 ACCDB 格式,您将以用户 Admin 的身份工作。您可以在“立即”窗口中确认该点。 (用 Ctrl+g 去那里)

? CurrentUser()
Admin

由于 Admin 没有对 MSysObjects 的读取 (SELECT) 权限,请执行 DDL 语句以授予 Admin 该权限。

strDdl = "GRANT SELECT ON MSysObjects TO Admin;"
CurrentProject.Connection.Execute strDdl

【讨论】:

  • +1 太棒了!这也允许 ACE/OLEDB 从 Access 外部访问 .accdb 文件中的 MSysObjects。
  • 使用 ODBC 连接和 accdb 文件上的访问 UI 查询窗口尝试此操作 - 这是无效的 SQL。
【解决方案2】:

这对我有用,因为这是为此提出的第一个 SO 问题:

  1. 这是一个 MDB 文件。不知道别人。 我知道这不是问题所要求的。但是,许多其他通过谷歌到达这里的人也使用 StackOverflow 问题/答案,就像我一样,我正在使用 MDB。我希望这个答案对其他人有用。

  2. 打开 MS Access GUI。不知道怎么做

  3. 转到工具...选项...

  4. 点击“查看”标签

  5. 选择“隐藏对象”、“系统对象”

  6. 关闭标签

  7. 转到工具...安全...用户和组权限

  8. 选择所有表名,包括MSysObjects

  9. 单击所有“权限”复选框,以便将所有条目设置为“已选中”

  10. 根据需要申请/确定

【讨论】:

  • 我在第 1 点中提到了这一点。这里的问题对使用这两种格式的人都有用。如果您在谷歌上搜索此错误消息,这就是出现的 SO 问题。因此,对于某些人来说,有一个可行的答案总比没有答案要好。
  • 赞成,因为 #1 正是十年后我偶然发现这一点时所寻找的。谢谢@zzzeek
【解决方案3】:

使用 DAO tabledefs 集合

Sub TableDefs()

    Dim db As dao.Database
    Dim tdfLoop As dao.TableDef

    Set db = CurrentDb
    With db
        Debug.Print .TableDefs.Count & " TableDefs in " & .name
        For Each tdfLoop In .TableDefs
            Debug.Print "    " & tdfLoop.name
        Next tdfLoop
    End With

End Sub

【讨论】:

  • 这似乎很明智,但 OP 说“我希望能够仅使用 SQL 语句获取表名”
  • 原始问题中没有任何内容表明这是从 Access 外部完成的,所以在我看来,如果您要获取表列表,您将使用他们。如果不使用 SQL 字符串作为组合/列表框的行源,您将使用代码来使用结果列表,在这种情况下,您是否使用 TableDefs 集合遍历基于 Recordset 的集合几乎没有任何区别SQL 语句。
  • Remou,当然,他说只使用SQL语句。我想如果他现在还没有得到答案,那么他应该尝试其他方法。
  • 解释为什么 在这里:我试图在 Cygwin 上使用 Perl 列出 *.mdb 文件中的表;尝试使用 DBD::ODBC 执行此错误会失败,并且无法安装可用于执行 DAO 的 Win32::OLE 模块。
【解决方案4】:

看起来像是权限问题。尝试打开数据库并转到安全权限(在工具-> 安全-> 用户和组权限下)确保您对数据库具有管理员访问权限。

如果您不这样做,您可能必须以用户身份登录数据库并授予自己权限

【讨论】:

  • -1 工具->安全->Access 2007 中不存在用户和组权限
  • @jaywon:如果您正在查看 MDB 文件,则该菜单选项确实存在。如果您正在查看不支持 Jet 用户级安全性的 ACCDB 文件,它将不会显示。所以,你的评论是错误的。
【解决方案5】:

我能够使代码与 MDB 文件一起使用。我可以选择使用功能区上的“数据库工具 - 用户和权限”设置用户权限。此选项仅适用于 MDB 文件。现在的问题是让它与 ACCDB 文件一起工作。

这是我的代码:

Dim DBFile As String  
Dim Connection As ADODB.Connection 
Dim Recordset As New ADODB.Recordset

DBFile = "C:\Documents and Settings\User\Desktop\Son.mdb"

Set Connection = New ADODB.Connection  <br/>
Connection.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source= " & DBFile & ";"  

SQLString = "SELECT MSysObjects.Name AS table_name" & _
"FROM MSysObjects WHERE (((Left([Name],1))<>" & """~""" & ")" & _
"AND ((Left([Name], 4))<>" & """MSys""" & ")" & _
"AND ((MSysObjects.Type) In (1,4,6)));order by MSysObjects.Name" 

Set Recordset = New ADODB.Recordset 
Recordset.Open SQLString, Connection

问题是我无法使用 ACCDB 文件。

【讨论】:

    猜你喜欢
    • 2013-11-27
    • 2012-03-10
    • 2015-12-26
    • 1970-01-01
    • 2017-02-12
    • 2013-05-23
    • 1970-01-01
    • 2014-02-09
    • 1970-01-01
    相关资源
    最近更新 更多