【问题标题】:Possible to join two recordsets using VBA/ADO?可以使用 VBA/ADO 连接两个记录集吗?
【发布时间】:2013-01-27 16:52:23
【问题描述】:

目标是将 Access 表与 SQL Server 表中的匹配数据连接起来。我会在 Access 中使用链接表来执行此操作,但我遇到了 Access 的 BigInt 问题(我会创建一个视图以将 BigInt 转换为 Int,但现在这不是一个选项)。

所以我一直在尝试创建两个记录集并将它们加入 VBA/ADO。连接的左侧是带有 Season 和 WeekNum 的 Access 表,连接的右侧是带有 Season 和 Weeknum 以及其他数据的 SQL Server 表。这工作正常,直到我尝试创建作为连接结果的第三个记录集(在此示例中,我没有尝试进行连接,只是通过从 Access 记录集中选择连接的第一部分)。当我执行 Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset ' 时,出现类型不匹配错误。

甚至可以连接两个记录集吗?如果是这样,这是如何完成的?

Function Join()

    Dim SQL_Server_Connection As ADODB.Connection
    Set SQL_Server_Connection = New ADODB.Connection
    Dim SQL_Server_Query As String
    Dim SQL_Server_Recordset As New ADODB.Recordset

    Dim Access_Recordset As New ADODB.Recordset

    Dim ObjConnection As ADODB.Connection
    Set ObjConnection = CreateObject("ADODB.Connection")
    Dim ObjRecordset3 As New ADODB.Recordset

    ' Get data from Bump Table 3:
    Access_Recordset.Open "SELECT * FROM [Bump Table 3]", CurrentProject.Connection

    ' Open connection to SQL Server:
    SQL_Server_Connection_String = "DSN=MySQLServer"
    SQL_Server_Connection.Open SQL_Server_Connection_String

    ' Define the SQL Server query:
    SQL_Server_Query = "SELECT Season, WeekNum FROM TE"

    ' Populate the SQL_Server_Recordset:
    SQL_Server_Recordset.Open SQL_Server_Query, SQL_Server_Connection, adOpenDynamic, adLockOptimistic

    'Join Access_Recordset (Table: Bump Table 3) to SQL_Server_Recordset (Table: TE)
    Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset ' Type Mismatch error on this line

    Access_Recordset.Close
    Set Access_Recordset = Nothing

    SQL_Server_Recordset.Close
    Set SQL_Server_Recordset = Nothing

    SQL_Server_Connection.Close

End Function

* 更新 *

我想出了如何实现我的最终目标,即根据两个表共有的帐号字段,从 SQL Server 获取有关 Access 表中帐号列表的数据。意识到我可以在 SQL Server 上创建一个持久临时表,我结合使用 DAO 和 ADO 从 Access 表中获取值并创建一个临时表。我所要做的就是运行引用临时表的传递查询。唯一奇怪的事情(此时这不是问题)是如果我创建临时表并在 VBA 中运行传递查询,则此设置有效。但是如果我在 VBA 中创建临时表并双击传递查询,Access 会说找不到临时表。无论如何,这是代码:

Public Sub Insert_Into_Access_From_ADO_Recordset_Using_PTQ_Simpler()

    Dim dbs As DAO.Database
    Set dbs = CurrentDb()

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

    Dim rst As ADODB.Recordset

    'Open SQL Server
    Dim str_cnn As String
    str_cnn = "MYDSN"

    cnn.Open str_cnn

    ' Drop the temp table:

        Dim str_SQL_Drop_Temp_Table As String

        str_SQL_Drop_Temp_Table = "IF OBJECT_ID('tempdb..##BumpData','U') IS NOT NULL "
        str_SQL_Drop_Temp_Table = str_SQL_Drop_Temp_Table & " DROP TABLE ##BumpData "

        cnn.Execute str_SQL_Drop_Temp_Table


    ' Create the temp table:

        Dim str_SQL_Create_Temp_Table As String

        str_SQL_Create_Temp_Table = " CREATE TABLE ##BumpData "
        str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & "("
        str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & " ID INT "
        str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & " ,   AccountNumber VARCHAR(Max)"
        str_SQL_Create_Temp_Table = str_SQL_Create_Temp_Table & " " & ")"

        cnn.Execute str_SQL_Create_Temp_Table


    ' Insert values from the Access table into the temp table
    ' by looping through the Access table as a recordset:

        Dim rst_DAO As DAO.Recordset
        Set rst_DAO = dbs.OpenRecordset("Bump Data")

        Dim str_SQL_Insert As String

        rst_DAO.MoveFirst

        With rst_DAO
            Do While Not rst_DAO.EOF
                'str_Loan_Number_List = str_Loan_Number_List & "'" & Trim(rst![Loan Number]) & "'" & ","
                str_SQL_Insert = " INSERT INTO ##BumpData VALUES (" & rst_DAO![ID] & ",'" & Trim(rst_DAO![Loan Number]) & "') "
                cnn.Execute str_SQL_Insert
                .MoveNext
            Loop
        End With

    ' Run the pass-thru query which joins to the temp table:
    DoCmd.SetWarnings False
    DoCmd.RunSQL "SELECT * INTO [Bump Results] FROM [Bump PTQ]"
    DoCmd.SetWarnings True

End Sub

【问题讨论】:

  • 链接表的Big Int 问题仅发生在动态集模式下,因为 Access 不支持相同级别的数字字段。只要您只需要在查询中使用它以供参考而不更新数据,那么您可以从链接表创建访问查询并将模式设置为Snapshot,或者失败可能是Pass through query
  • @MattDonnan 我不明白你的评论。当我在包含字段表达式TypeName(bigint_fld) 的链接表上创建查询时,它会从快照或动态集模式回复“字符串”。我认为问题是关于将 Access 整数字段与 SQL Server Big Int 字段连接起来。
  • @HansUp 你是对的,我提到它的原因是因为我记得在 2003 年,如果你打开一个使用BigInt 作为PK 的链接表,那么你经常会看到一个#Deleted 的流而不是由于 dynaset 模式无法处理精度的数据,在快照中查看否定了这个问题,尽管我可能在尝试链接查询中的表时也可能导致问题。虽然与问题的直接问题无关,但它可能会派上用场。

标签: ms-access ado


【解决方案1】:

你报告的这行触发了错误:

Set ObjRecordset3 = "SELECT * FROM " & Access_Recordset

= 符号的右侧尝试将字符串与ADODB.Recordset 对象连接起来。这可能是编译错误的直接原因。但是,这不是该行的唯一问题。 Set <recordset object> = "any string value" 将不起作用。最后,Access SQL 不支持 FROM <recordset object> 用于任何类型的记录集对象(ADO 或 DAO)。

我认为您应该寻找一种更简单的方法。在以下查询中,dbo_BigIntTable 是指向 SQL Server 表的 ODBC 链接。它包括一个字段bigint_fld,其SQL Server 数据类型为BigInt。但是,Access 将该字段视为文本类型。因此,我可以将它与相当于 Long Integer 字段 (tblFoo.id) 的字符串连接起来。

SELECT tblFoo.id, dbo_BigIntTable.bigint_fld
FROM
    tblFoo
    INNER JOIN dbo_BigIntTable
    ON CStr(tblFoo.id) = dbo_BigIntTable.bigint_fld;

Access 查询设计器抱怨它无法在设计视图中显示该联接,但我能够从 SQL 视图创建联接并且工作正常。

【讨论】:

  • 谢谢你。抱歉回复晚了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-02
  • 2018-06-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多