查询从SQL到MS Access的数据:本地表与传递表

时间:2018-03-29 07:38:15

标签: sql-server vba ms-access access-vba connection-string

我创建了一个应用程序,它使用以下逻辑从SQL查询数据到我的MS Access App。

  1. 使用ODBC连接我执行存储过程
  2. 使用此项被指定为传递查询以在本地提取数据。
  3. 它看起来像这样:

    strSQL = "EXEC StoredProcedure " & Variable & "
    
    Call ChangeQueryDef("qryPassThrough", strSQL)
    Call SQLPassThrough(strQDFName:="qryPassThrough", _
          strSQL:=strSQL, strConnect:=gODBCConn)
    
    Me.frmDataSheet.Form.RecordSource = "qryPassThrough"
    

    但是,最近我们使用高可用性故障转移系统将SQL Server升级到2016年 - 因此我们的连接字符串已更改为连接到监听器,如下所示:

    gODBCConn = "ODBC;Driver= {SQL Server Native Client 11.0};Trusted_Connection=Yes;Regional=Yes;Database=" & varDB & ";MultiSubnetFailover=Yes;IntegratedSecurity=SSPI;Server=tcp:SERVER_LISTENER,1433;"
    

    但是,看起来在连接字符串中使用SQL Server Native Client与我们原来的SQL Server不一样。某些数据类型已更改,但在Access中无效。

    我是否有更好的方法从SQL查询数据并使用ADO或其他方法在访问中保留/显示此数据?

    编辑基于评论:

    • 我遇到的问题是我在SQL中使用数据类型:Decimal(12,2)。通过一些测试和实验,这在使用ODBC传递查询时似乎失败了。但是将数据类型更改为Float似乎工作正常。然后还有其他数据类型似乎也出错,我还没有找到。它似乎有一些我不知道的差异,我很想找到一种更好的方法将数据加载到我的Access应用程序中。

    编辑2 这是我得到的与数据类型问题有关的错误消息。 enter image description here

2 个答案:

答案 0 :(得分:1)

听起来你真的不想让底层数据结构与Access兼容,所以:

如何将ADODB记录集加载到数据表格式

创建表单

首先,创建一个数据表表单。对于此示例,我们将命名我们的表单frmDynDS。使用256个文本框填充表单,名为Text0到Text255。要使用文本框填充表单,可以在表单处于设计视图时使用以下辅助函数:

Public Sub DynDsPopulateControls()
    Dim i As Long
    Dim myCtl As Control
    For i = 0 To 255
        Set myCtl = Application.CreateControl("frmDynDS", acTextBox, acDetail)
        myCtl.NAME = "Text" & i
    Next i
End Sub

VBA将记录集绑定到表单

首先,我们允许表单通过允许它自己引用来保持表单:

(在frmDynDS的代码模块中全部开启)

Public Myself As Object

然后,我们将添加VBA以使其加载记录集。我使用Object代替ADODB.Recordset来允许DAOADODB记录集。

Public Sub LoadRS(myRS As Object)
    Dim i As Long
    Dim myTextbox As textbox
    Dim fld As Object
    i = 0
    With myRS
        For Each fld In myRS.Fields
            Set myTextbox = Me.Controls("Text" & i)
            myTextbox.Properties("DatasheetCaption").Value = fld.NAME
            myTextbox.ControlSource = fld.NAME
            myTextbox.ColumnHidden = False
            i = i + 1
        Next fld
    End With
    For i = i To 255
        Set myTextbox = Me.Controls("Text" & i)
        myTextbox.ColumnHidden = True
    Next i
    Set Me.Recordset = myRS
End Sub

使用表单

(所有在使用frmDynDS的表单模块中)

  1. 作为独立的数据表格式

    Dim frmDS As New Form_frmDynDS
    frmDS.Caption = "My ADO Recordset"
    frmDS.LoadRS MyAdoRS 'Where MyAdoRS is an open ADODB recordset
    Set frmDS.Myself = frmDS
    frmDS.Visible = True
    frmDS.SetFocus
    

    请注意,您可以打开此表单的多个实例,每个实例都绑定到不同的记录集。

  2. 作为子表单(保持子表单控件不绑定)

    Me.MySubformControl.SourceObject = "frmDynDS"
    Me.MySubformControl.Form.LoadRS MyAdoRS 'Where MyAdoRS is an open ADODB recordset
    
  3. 警告:Access在排序和过滤数据表表单时使用命令文本。如果它包含Access的语法错误(因为它是T-SQL),则在尝试排序/筛选时会出错。但是,当语法有效但SQL无法执行时(例如,因为您正在使用不再可用的参数),Access将很难崩溃,丢失任何未保存的更改并可能损坏您的数据库。即使您禁用排序/过滤,您仍然可以在尝试排序时触发硬崩溃。您可以在SQL中使用注释来使语法无效,从而避免这些崩溃。

答案 1 :(得分:0)

您之前使用过的非常古老的原始ODBC驱动程序for SQL Server简称为SQL Server。您做出了正确的决定,使用较新的驱动程序来支持故障转移群集。但我不建议使用SQL Server Native Client。微软说, It is not recommended to use this driver for new development. 相反,我会使用Microsoft ODBC Driver 13.1 for SQL Server。这是最新的和推荐的(由Microsoft)SQL Server的ODBC驱动程序。

您的主要问题似乎是通过ODBC层在Access和SQL Server之间的转换问题。因此,使用更现代的驱动程序可能会使这个问题消失。 - 我不知道它是否能解决你的问题,但这是我要尝试的第一件事。

相关问题