将嵌入式连接字符串中的mdw文件指定给另一个Jet mdb:可能吗?

时间:2009-05-14 11:24:20

标签: ms-access jet

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

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

替代地

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

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

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

但这只适用于两个mdb共享相同的mdw时。

如何指定用于保护其他mdb的mdw文件的路径?可能吗?如果没有,为什么不呢?

P.S。多年前我在this Access newsgroup post问了这个问题,但没有得到答复。 Access MVP让我确信这是不可能的,我放弃了;我不记得细节,但它与底层架构有关(工作空间只支持一个工作组文件,并且Jet查询没有机制来实例化新工作区?无论如何都是这样的)。

this SO comment引发了我的兴趣。

5 个答案:

答案 0 :(得分: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.)使用限制访问限制最小的特殊帐户。您可能还建议您采取一些步骤来混淆代码中的信息以及保护项目的密码实际上不会以任何方式模糊存储在文件中的文本。

答案 1 :(得分:1)

简单回答:这是不可能的。

答案 2 :(得分:0)

嗯......实际上你可以使用连接字符串。它最适合SQL Server。我只是展示它如何与Access一起工作。我试图提出的一点是,有一个有效的语法......只是Access不允许你用Access做到这一点。 (如果连接到另一种类型的数据库,它允许你这样做。)有趣的是,该功能与其他类型的数据库兼容而不是Access ...当它的访问权限,但是确实如此。

虽然如果使用相同的MDW保护它们,那么您只需执行此操作,查询将在当前登录用户的上下文中运行:

SELECT *
FROM Table1 IN 'C:\Users\Oorang\Documents\db2.mdb';

答案 3 :(得分:0)

也许我应该重新整理并澄清:)在原始问题的背景下,答案是: 如果数据库是:Access,并且具有不同的mdw,则无法通过SQL / Query Builder执行此操作。 然而,如果两个数据库都是Access并且具有相同的 mdw,(如后面的注释所示)那么你可以通过SQL / Query来实现生成器。在该特定情况下,您不会(不能)通过连接字符串执行此操作,您将按照下面的步骤1-4执行此操作,然后将步骤5a替换为5b。

如果数据库都是Access并且具有不同的 mdw,则指定不同工作组的唯一方法是使用连接字符串。 然而如果您尝试通过连接字符串属性(在下面的步骤5a中),SQL / Query Builder将抛出ISAM错误。因此,无法通过“查询”构建器执行此操作。您可以使用ADO使用ADO执行此操作,如我之前发布的示例所示。

请记住,查询构建器中的连接字符串属性适用于 - 访问数据库,源数据库适用于具有相同(或否)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视图。看看是什么建的。
  7. 但这种方法几乎无关紧要,但对于 - 访问数据库有效,不适用于Access 。 (我知道这有点令人沮丧。)

    正在使用的连接字符串示例:

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

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

    就像一个FYI,你使用连接字符串,如上所示,但是如果你使用Source Db属性,你将得到以下内容:)(我在发布之前测试了所有的例子:))

    SELECT *
    FROM Table1 IN 'C:\Users\Oorang\Documents\db2.mdb';
    

答案 4 :(得分:0)

使用 ACCESS 时,您可以使用用户定义的函数来读取来自其他工作组的数据。

对Access的限制是因为只有Access具有允许您使用用户定义函数的VB挂钩。它等同于使用SQL服务器用户定义的函数 - 只有在您拥有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中,您可以使用该工作区从另一个数据库中读取数据,使用“任何”工作组文件。

注意:如果从select查询中调用此方法,请将dbe和ws以及db和rs全局设置为全局,这样每次触摸记录中的字段时都不会打开文件。然后功能只有

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

注意:如果您真的想要,可以将更新查询放入从select语句调用的udf中。如果你希望稍后在thedailywtf.com上发布它,请这样做。

PS:这是一个不寻常的解决方案。我在2004年左右,但你不会通过张贴到“gettingstarted”获得这个