在 Access 中附加 tabledef 时出现错误 3045 或 3356

Posted

技术标签:

【中文标题】在 Access 中附加 tabledef 时出现错误 3045 或 3356【英文标题】:Error 3045 or 3356 when appending a tabledef in Access 【发布时间】:2013-03-05 17:51:18 【问题描述】:

我正在使用 MS Access 2003(没有其他可用)为快照样式数据库构建一个临时后端,其中涉及将一些链接的 tabledefs 添加到临时后端。该代码已经运行了大约 3 周,但截至今天下午早些时候,开始抛出 3356(即机器 Y 上的用户 X 已经以独占模式打开了数据库......)或 3045(大致无法打开数据库在独占模式下),取决于我是否已经在 Access 中建立了连接。

错误代码大致(略微修剪):

Private Sub AddTabledefToDb(dbC As DAO.Database, dbTarget As DAO.Database, strLinkedName As String)
    Dim strPath As String, tdfLinked As DAO.TableDef
    strPath = strGetPathFromConnect(tdfLinked.Connect)

    Set tdfLinked = dbC.TableDefs(strLinkedName)

    ' With the lines below, error thrown is 3356; without 3045 '
    Dim dbLinkedTableIn As DAO.Database
    Set dbLinkedTableIn = Application.DBEngine.Workspaces(0).OpenDatabase(strPath, False, True, tdfLinked.Connect)

    Dim tdfNew as DAO.TableDef
    Set tdfNew = dbTarget.CreateTableDef(Attributes:=dbAttachedTable)
    tdfNew.Name = tdfLinked.Name
    tdfNew.SourceTableName = tdfLinked.SourceTableName
    tdfNew.Connect = tdfLinked.Connect
    dbTarget.TableDefs.Append tdfNew ' Throws 3045 without the lines above or 3356 with them ' 

    ' If needed... ' 
    dbLinkedTableIn.Close
    Set dbLinkedTableIn = Nothing

End Sub

我怀疑其原因可能与我打开包含我直接链接到的表的数据库时显示的消息有关,即它仅在只读模式下可用(我是相当肯定以前不是这种情况)。但是,我不清楚为什么我的代码需要的不仅仅是只读访问权限,而且我无法弄清楚它为什么要尝试获取它(尤其是当我事先以只读模式显式打开数据库时)。

任何帮助将不胜感激。

谢谢

【问题讨论】:

嗯,这可能是很多事情。假设某人实际上并没有以独占模式打开其中一个数据库(您可能已经检查过),这听起来像是一个权利问题。即使在您链接到的数据库上,您也需要有权创建/修改/删除 .ldb 锁定文件,因此如果这是一个网络共享,您可能希望从那里开始。 嗯...好吧,我知道我可以创建一个 .idb,因为它是在我显式打开数据库时创建的,并在关闭/无对象时删除(只是查看文件夹)。我隐隐约约地想知道这是否与 2gb 限制有关 Access 虽然......我试图连接到的 db 显示为 1.87gb(不要问),但想想它很可能是 2 万亿字节(考虑到 1000 和 1024 等之间的区别)。今天早上再试一次,它似乎起作用了(触摸木头)。不过,我真的很困惑为什么它一开始就坏了。 @tobriand 我认为您对文件大小的怀疑是正确的,显示 1.87GB 应该等于以字节为单位的 2GB 限制。当您达到这些限制时,Access 会触发权利侵犯,而不是更有意义的 Out of Space 错误。数据库最近是否正在压缩和修复?如果是这样,您可能需要考虑将一些表拆分到另一个 mdb 文件中。 好的,我发现这是由于 Debrah 在这里谈到的同一问题:Link。但是,解决方法仍然没有运气,因为我无法控制谁将创建指向此 Access 数据库的 Excel 链接。任何想法都非常感谢。 【参考方案1】:

我想我已经找到了答案:不要使用 DAO,而是使用 ADO。大致见下文。目前,我还没有将Mode 属性设置为读取,但初步测试表明它至少可以在不这样做的情况下运行。

Dim cn As ADODB.Connection
Dim tbl as ADOX.Table
Dim cat as ADOX.Catalog

Set cn = New ADODB.Connection
cn.Provider = "Microsoft.Jet.OLEDB.4.0"
cn.Open dbTarget.Name ' Path of the db the linked table needs to end up in'

Set cat = New ADOX.Catalog
cat.ActiveConnection = cn

Set tbl = New ADOX.Table
Set tbl.ParentCatalog = cat

tbl.Name = tdfLinked.Name
tbl.Properties("Jet OLEDB:Link Datasource") = strGetPathFromConnectString(tdfLinked.Connect)
tbl.Properties("Jet OLEDB:Link Provider String") = "MS Access"  ' If Password protected, details go here ' 
tbl.Properties("Jet OLEDB:Remote Table Name") = tdfLinked.SourceTableName
tbl.Properties("Jet OLEDB:Create Link") = True

cat.Tables.Append tbl

cn.Close
Set tbl = Nothing
Set cat = Nothing
Set cn = Nothing

粗略地说,看起来 ADO 很乐意创建链接表而无需在 Code 中获取读/写访问权限,而 DAO 则不然。

【讨论】:

在我接受我的回答之前等待几天,因为很有可能会再次出现问题!

以上是关于在 Access 中附加 tabledef 时出现错误 3045 或 3356的主要内容,如果未能解决你的问题,请参考以下文章

MS-Access 2003 CurrentDb.TableDefs("tablename").Connect 数据库啥都不是

尝试在 js 中附加路由参数时出现问题

为啥在 Access 中使用 UNION ALL 时出现 ODBC 连接失败错误?

在 jQuery.each 中附加元素时出现错误

尝试在 Access 中使用“添加”按钮时出现编译错误

为啥在尝试将 UIPopover 附加到不同类中的 UIButton 时出现此构建错误?