ms访问连接到同一服务器上的2个sql server数据库

时间:2015-09-01 01:52:13

标签: sql-server ms-access

我正在使用Access前端表单转换Access应用程序以使用SQL Server后端。听起来很有趣我知道。

此应用程序需要对同一服务器上的2个SQL Server数据库进行数据访问。有许多内联sql查询字符串尝试在单个ADODB连接上同时连接到两个数据库。这是失败的,因为我期待记录但没有返回。

解决此问题的最佳方法是什么?有没有办法使用这些sql字符串或必须将它们都转换为存储过程?谢谢你的帮助。

以下是一些代码:

Dim conn As ADODB.Connection
Set conn = New ADODB.Connection

Dim rst As ADODB.Recordset
Set rst = New ADODB.Recordset

With conn
    .Provider = "sqlncli11" 
    .ConnectionString = "Server=[MY_SERVER];Database=[MY_DATABASE];User Id=sa; Password=password;"
    .Open
End With

Dim str As String
str = "SELECT TABLE_DB1.Parent_Item_No FROM TABLE_DB1 INNER JOIN [DB2].[dbo].TABLE_DB2 ON (TABLE_DB1.Comp_Item_No = " & _
            "TABLE_DB2.item_no) AND (TABLE_DB1.Loc = TABLE_DB2.loc) " & _
            "GROUP BY TABLE_DB1.Parent_Item_No " & _
            "HAVING (((TABLE_DB1.Parent_Item_No)='" & str_Assembly & "'));"

With rst
    .Open str, conn, adOpenKeyset, adLockOptimistic ' this fails to return records

    If .RecordCount > 0 Then 
        'Do Stuff
    Else
    'Do Other Stuff
    End If 

End With

6 个答案:

答案 0 :(得分:1)

您只需查看RecordCount。看看这个:slxdeveloper.com/page.aspx?action=viewarticle&articleid=33有些记录集类型没有填充RecordCount属性(尽管adOpenKeyset应该)。如果您使用While Not .EOF和.BOF会发生什么?您的代码中RecordCount的实际值是多少?

答案 1 :(得分:0)

是否可以从SQL运行保存到访问文件的查询?我只有将数据直接导入访问权限。我在设置ODBC数据库并转到数据时确实取得了成功 - >获取外部数据 - >来自其他来源 - >来自微软查询

我自己成功使用的另一种方法是使用microsoft的power query add-on。 https://www.microsoft.com/en-us/download/details.aspx?id=39379

尽管如此,我最常做的还是使用SQL导入/导出工具。我没有屏幕截图或具体说明,因为我现在没有工作,但这可以直接写入文本文件,Access数据库,所有内容。我太爱了。获得正确的驱动程序肯定是一个循环。如果您使用的是64位并且遇到问题,那么这就是您需要的驱动程序。 http://www.microsoft.com/en-us/download/details.aspx?id=13255 我所做的是:

  • 设置我的源(SQL 11本机客户端),选择您从
  • 中提取的数据库
  • 指定outfile类型和位置(我认为它已经存在)
  • 当提示您指定是从表和视图中提取数据还是编写查询时,请选择“编写查询”。
  • 浏览导入器的其余部分,您可以稍后在查看转换时编辑sql语句,并指定传输失败或忽略错误等。

我个人仍然使用导入导出工具进行各种大小的传输,因为它很难获得所有正确的驱动程序并让SQL变得像我想要的那样。 (并且没有管理员权限我厌倦了问我的老板)。

我希望其中一个解决方案能为您提供帮助!

答案 2 :(得分:0)

我已经勾勒出更合适的解决方案和快速解决方案......

更合适的修复方法是数据层模式。这个修复有很多,它可能需要一些应用程序结构更改。这在另一个问题中进行了深入讨论: Data Access Layer design patterns

一个非常简单的解决方法是使用Access Linked表。链接表的工作方式与普通的Access表类似,只是数据在SQL Server上存储和更新。它基本上是一个内置的SQL Server数据访问层。它不是一个优雅的解决方案,但它可以立即启动并运行。更多信息可以在这里找到: https://support.office.com/en-us/article/Import-or-link-to-SQL-Server-data-a5a3b4eb-57b9-45a0-b732-77bc6089b84e#bm2

使用链接表要注意的是,某些访问查询和表单在过滤之前会检索所有记录,并且可以锁定表,这样如果您拥有大量数据和大量用户,最终可能会遇到一些性能问题。

答案 3 :(得分:0)

考虑使用SQL Server SYNONYM功能将一个数据库中的对象的别名添加到另一个数据库中。然后只需更新所有查询即可使用一个数据库。

此外,您可以将两个数据库与每个数据库合并,或者将其中一个数据库合并到一个新模式中以使它们分开。如果数据库中有大量存储过程,视图和函数,这可能很难。这可能是一个可怕的答案,但也可能确实这两个数据库本来就不应该是分开的。

答案 4 :(得分:0)

INNER JOIN中,您使用DatabaseName.Schema.

为表名添加了前缀
... FROM TABLE_DB1 INNER JOIN [DB2].[dbo].TABLE_DB2 ...

但是你没有在发生TABLE_DB2的其他地方这样做。

所以你要么改变这个:

ON (TABLE_DB1.Comp_Item_No = TABLE_DB2.item_no) AND (TABLE_DB1.Loc = TABLE_DB2.loc)

......对此:

ON (TABLE_DB1.Comp_Item_No = [DB2].[dbo].TABLE_DB2.item_no) AND (TABLE_DB1.Loc = [DB2].[dbo].TABLE_DB2.loc)

(我更喜欢)您可以在FROM子句中为表名使用别名:

... FROM TABLE_DB1 t1 INNER JOIN [DB2].[dbo].TABLE_DB2 t2...

...然后你在其他地方使用别名:

str = "SELECT t1.Parent_Item_No FROM TABLE_DB1 t1 INNER JOIN [DB2].[dbo].TABLE_DB2 t2 ON (t1.Comp_Item_No = " & _
            "t2.item_no) AND (t1.Loc = t2.loc) " & _
            "GROUP BY t1.Parent_Item_No " & _
            "HAVING (((t1.Parent_Item_No)='" & str_Assembly & "'));"

其他背景资料:

如果通过ADO连接到SQL Server,则直接连接到一个数据库 - 连接字符串中的数据库:

.ConnectionString = "Server=[MY_SERVER];Database=[MY_DATABASE];User Id=sa; Password=password;"

因此,在您的情况下,您要连接的数据库名为MY_DATABASE。您通过ADO执行的任何SQL都将转到该数据库。

如果您需要从同一服务器上其他数据库获取数据,则需要在{strong>所有位置使用DatabaseName.Schema.作为名称的前缀

所以我们假设我们有:

  • MY_TABLE
  • 中的表MY_DATABASE
  • 同一服务器上OTHER_TABLE中的表OTHER_DATABASE
  • 两个表都具有架构dbo (SQL Server中的默认值)

使用上面的连接字符串(连接到MY_DATABASE),您可以按如下方式加入它们:

select *
from MY_TABLE 
  inner join OTHER_DATABASE.dbo.OTHER_TABLE
  on MY_TABLE.SomeColumn = OTHER_DATABASE.dbo.OTHER_TABLE.OtherColumn
where OTHER_DATABASE.dbo.OTHER_TABLE.EvenAnotherColumn = 'foo'

请参阅?在我使用OTHER_TABLE的任何地方,我都用OTHER_DATABASE.dbo.作为前缀。

PS:
使用sa用户连接到具有应用程序的数据库是bad practicesa用户拥有最高权限 您应该使用Windows身份验证或为您的应用程序创建专用的SQL用户。

答案 5 :(得分:0)

考虑将SQL存储在传递查询中而不是VBA代码中。您可以使用传递查询的querydef对象的.sql属性副本来应用过滤器,并使用它们在运行时在表单中输入的条件对其进行修改。