【问题标题】:Grant read permission for MSysObjects授予 MSysObjects 的读取权限
【发布时间】:2015-12-26 21:49:39
【问题描述】:

我需要获取数百个 MS Access 数据库的元数据,因此我需要自动化元数据收集过程。 我想查询here 描述的内容,但在查询数据库之前,我需要对MSysObjects 表的读取权限。

我不断收到以下错误:

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

所以我挖得更深了:

我已阅读 C# 部分中有关类似问题的文章(see herethis one)。

我编写了一个简单的脚本,可以很好地用于创建表等,但是我在设置读取访问权限时遇到了问题。

$ScrUsr = $(whoami)
Write-Host $ScrUsr

$cmd = "GRANT SELECT ON MSysObjects TO [$ScrUsr]"
Write-Host $cmd

Function Invoke-ADOCommand($Db)
{
  $connection = New-Object -ComObject ADODB.Connection
  $connection.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$db;" )
  $command = New-Object -ComObject ADODB.Command
  $command.ActiveConnection = $connection
  $command.CommandText = $cmd
  $rs = $command.Execute()
  $connection.Close()
} 

$Db = "C:\Temp\test1.accdb"

Invoke-ADOCommand -db $Db 

执行脚本会引发以下错误原因:

无法打开 Microsoft Office Access 数据库引擎工作组信息文件。

如何允许对MSysObjects 的读取权限?

【问题讨论】:

  • 我认为这不是问题,但你的函数参数有异常Invoke-ADOCommand($Db, $Command) 当你 调用 函数时你不使用$command 所以只是去掉它。该数据库密码是否受保护?
  • 感谢提示,已经修复,脚本可以工作,因为 $command 变量将在函数中设置。 Nop DB 不受密码保护。我已经尝试过 Grant to Public,但这也没有用。
  • 你试过了吗? ...GRANT SELECT ON MSysObjects TO Admin;
  • Jepp,我的初始语句是针对 MdB 触发的,同样的 errorMsg

标签: powershell ms-access metadata adodb office-automation


【解决方案1】:

您必须解决两个问题:

  1. 在与 Access ACCDB 数据库交互时,您的代码将使用 Access 安全帐户“Admin”。其他 Access 安全帐户仅在您实施 Access 用户级安全 (ULS) 时可用,但该功能仅适用于 MDB 格式数据库。因此,使用 ACCDB,除了 “Admin” 之外,您不能 GRANT 向任何帐户发送任何内容。

  2. 您必须在连接字符串中包含“系统数据库”的位置

如果您不知道在哪里可以找到系统数据库,请打开 Access 并在“立即”窗口中检查此语句的输出。 (Ctrl+g 将打开立即窗口)

Debug.Print Application.DBEngine.SystemDb

我的系统数据库是 C:\Users\hans\AppData\Roaming\Microsoft\Access\System1.mdw 在下面的代码示例中替换你的。

我对 Powershell 不是很精通,但是这个示例对我来说运行没有错误。 (请务必同时更改$Db$SystemDb。)

$ScrUsr = $(whoami)
Write-Host $ScrUsr

$cmd = "GRANT SELECT ON MSysObjects TO Admin;"
Write-Host $cmd

Function Invoke-ADOCommand($Db, $SystemDb)
{
  $connection = New-Object -ComObject ADODB.Connection
  $ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$db;Jet OLEDB:System database=$SystemDb;"
  Write-Host $ConnectionString
  $connection.Open($ConnectionString)
  $discard = $connection.Execute($cmd)
  $connection.Close()
} 

$Db = "C:\Users\hans\AccessApps\Sample.accdb"
$SystemDb = "C:\Users\hans\AppData\Roaming\Microsoft\Access\System1.mdw"

Invoke-ADOCommand -db $Db -SystemDb $SystemDb

【讨论】:

  • nop,如果有人使用 try and catch 错误处理来控制运行它,那将是一个不错的选择,但对于起点和测试目的,它是可用的。再次感谢。
猜你喜欢
  • 2013-11-27
  • 1970-01-01
  • 2017-04-07
  • 1970-01-01
  • 1970-01-01
  • 2010-12-28
  • 2014-06-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多