1

我可以在 Jet (mdb) 查询中使用以下语法从另一个 .mdb 文件中选择数据:

SELECT * FROM [Database=C:\Tempo\AnotherDB.mdb;].MyTable

或者

SELECT * FROM MyTable IN 'C:\Tempo\Another.mdb'

我想扩展它以使用工作组安全性,即用户级安全性 (ULS)。我知道如何指定用户 ID 和密码,例如

SELECT *
FROM
[Database=C:\Tempo\AnotherDB.mdb;UID=Admin;PWD=***;].MyTable

但这仅在两个 mdb 共享相同的 mdw 时才有效。

我将如何指定用于保护其他 mdb 的 mdw 文件的路径?是否可以?如果不是,为什么不呢?

PS 我多年前在这个 Access 新闻组帖子中问过这个问题,但没有收到任何回复。在 Access MVP 说服我这是不可能的之后,我放弃了;我不记得细节,但它与底层架构有关(工作区仅支持一个工作组文件,并且没有 Jet 查询实例化新工作区的机制?无论如何都是这样)。

这个 SO 评论激发了我的新兴趣。

4

5 回答 5

2

简短的回答是否定的。如果您使用源数据库,那么您不能指定另一个工作组,如果将其留空并指定一个有效的连接字符串,那么您将收到 ISAM 错误。(尽管该方法适用于其他数据库,例如 SQL Server。)示例(不起作用):

SELECT *
FROM Table1 IN '' [Provider=Microsoft.Jet.OLEDB.4.0;Password=foo;User ID=Oorang;Data Source=C:\Users\Oorang\Documents\db1.mdb;Persist Security Info=True;Jet OLEDB:System database=C:\Users\Oorang\Documents\Security.mdw];

但是,您可以使用 ADO 来完成。我不确定您在获得查询后要完成什么,但这里是如何将其放入记录集中:

Option Explicit
Sub ADODBExample()
    Dim cn As ADODB.Connection
    Dim rs As ADODB.Recordset
    Set cn = New ADODB.Connection
    cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Password=foo;User ID=Oorang;Data Source=C:\Users\Oorang\Documents\db1.mdb;Persist Security Info=True;Jet OLEDB:System database=C:\Users\Oorang\Documents\Security.mdw"
    Set rs = New ADODB.Recordset
    rs.Open "SELECT * FROM Table1;", cn
    Debug.Print rs.GetString
    rs.Close
    cn.Close
End Sub

值得注意的是,这两种方法最终都会对帐户凭据进行硬编码。A.) 提示用户提供上述信息,或 B.) 使用只读权限限制在最低限度的特殊帐户可能会更好。还建议您采取一些步骤来混淆代码中的信息,以及保护项目的密码实际上不会以任何方式混淆存储在文件中的文本。

于 2009-05-18T03:51:23.530 回答
1

简单的回答:不可能。

于 2009-10-16T09:40:18.787 回答
0

嗯...实际上你可以使用连接字符串。它最适用于 SQL Server。我只是展示了如果它与 Access 一起使用会怎样。我试图说明的一点是有一个有效的语法......只是 Access 不允许您使用 Access 执行此操作。(如果连接到另一种类型的数据库,它会让你这样做。)有趣的是,该功能与其他类型的数据库兼容,而不是 Access...当它是 Access时,但仍然如此。

尽管如果它们使用相同的 MDW 进行保护,那么您所要做的就是这样做,并且查询将在当前登录用户的上下文中运行:

SELECT *
FROM Table1 IN 'C:\Users\Oorang\Documents\db2.mdb';
于 2009-05-19T00:32:18.637 回答
0

也许我应该重新整合和澄清:) 在你原来的问题的上下文中,答案是:你不能通过 SQL/Query Builder 来做,如果数据库是:既是 Access,又具有不同的 mdw。但是,如果两个数据库都是 Access 并且具有相同的mdw(如您稍后的评论所示),那么您可以通过 SQL/Query Builder 来完成。在那种特定情况下,您不会(不能)通过连接字符串执行此操作,您将按照下面的步骤 1-4 执行此操作,然后将步骤 5a 替换为 5b。

如果数据库都是 Access 并且具有不同的mdw,则指定不同工作组的唯一方法是使用连接字符串。但是,如果您尝试通过连接字符串属性(在下面的步骤 5a 中),SQL/查询生成器将引发 ISAM 错误。所以你不能通过查询生成器来做到这一点。您可以使用 ADO 使用 VBA 来完成此操作,如我之前发布的示例中所示。

请记住,查询构建器中的连接字符串属性适用于Access 数据库,源数据库适用于具有相同(或没有)mdw 的 Access 数据库。对于具有不同mdws 的 Access 数据库,我知道的唯一解决方案是我之前发布的 VBA 解决方案。

现在关于直接在 SQL 中使用连接字符串。你可以这样做。但有一些警告:它不适用于其他 Access 数据库。如果您使用 SQL Sever dbo 表执行此操作,则必须编辑查询生成器生成的 SQL 以删除“dbo”。字首。

我认为最简单的方法是引导您完成我想说的内容。

  1. 设置到非访问数据库的工作连接字符串。(我建议保持简单,只需使用 Excel 文件。)
  2. 获得字符串后,在 Access 中打开查询生成器。
  3. 关闭选择表对话框。
  4. 按 Alt-Enter 打开查询属性。5a。在“Source Connect Str”中粘贴连接字符串。*5b。将路径粘贴到“源数据库”中的其他数据库。
  5. 现在添加您的表并构建您的查询。
  6. 转到 SQL 视图。看看建了什么。

但这几乎无关紧要,因为这种方法虽然对Access数据库有效,但对 Access 不起作用。(我知道这有点令人沮丧。)

使用的连接字符串示例:

SELECT [Sheet1$].F1
FROM [Sheet1$] IN '' [Excel 5.0;HDR=NO;IMEX=2;DATABASE=C:\Users\Oorang\Documents\Book1.xls];

我真的不认为将 OLE DB 连接字符串放入 IN 数据库子句是有效的 ACE/Jet 语法。

仅供参考,您使用连接字符串,如上所示,但如果您使用 Source Db 属性,您将获得以下内容:)(我在发布之前测试了所有示例:))

SELECT *
FROM Table1 IN 'C:\Users\Oorang\Documents\db2.mdb';
于 2009-05-20T18:44:20.423 回答
0

您可以在使用ACCESS时使用用户定义函数从另一个工作组读取数据。

对 Access 的限制是因为只有 Access 具有允许您使用用户定义函数的 VB 挂钩。它等同于使用 SQL Server 用户定义的函数——只有当你有 SQL Server 时才运行。

对只读的限制是因为 Access 不提供用户定义变量的挂钩,只提供用户定义的函数。

在 Access 中,在用户定义的函数中,您可以输入如下代码:

Dim dbe As DAO.DBEngine
Dim ws As DAO.Workspace
Dim db as DAO.database

    Set dbe = New DAO.PrivDBEngine
    dbe.SystemDB = "whatever.mdw"
    dbe.DefaultUser = "whatever"
    dbe.DefaultPassword = "whatever"

    Set ws = dbe.Workspaces(0)
    Set db = ws.opendatabase( ... )

在该 UDF 中,您可以使用该工作区从另一个数据库中读取数据,使用“whatever”工作组文件。

注意:如果您从选择查询中调用它,请将 dbe 和 ws 以及 db 和 rs 设为全局,这样您就不必在每次触摸记录中的字段时都打开文件。那么这个函数就有

if rs is empty then
   set dbe = ...
   ...
   set rs = db.openrecordset(...)
end if 
...

注意:如果您真的想要,您可以将更新查询放入从 select 语句调用的 udf 中。如果您希望稍后在 thedailywtf.com 上看到它,请执行此操作。

PS:这是一个不寻常的解决方案。我在 2004 年左右,但你不会通过发布到“入门”来得到这个

于 2013-08-19T01:49:42.060 回答