【问题标题】:Query data from SQL to MS Access: Local Tables vs Pass-Through Tables从 SQL 到 MS Access 查询数据:本地表与传递表
【发布时间】:2018-09-08 01:57:56
【问题描述】:

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

  1. 我使用 ODBC 连接执行存储过程
  2. 使用这被指定为传递查询以在本地提取数据。

看起来像这样:

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 中有使用以下数据类型的表:十进制 (12,2)。通过一些测试和试验,这在使用 ODBC 传递查询时似乎失败了。但是将数据类型更改为 Float 似乎可以正常工作。然后还有其他数据类型似乎也出错了,我还没有找到。似乎有一些我不知道的区别,我很想找到一种更好的方法将数据加载到我的 Access 应用程序中。

编辑 2 这是我收到的与数据类型问题有关的错误消息。

【问题讨论】:

  • 请具体说明:什么不起作用?你的表结构是什么? VBA 不是那么相关,但该查询的存储过程、sql 字符串和 SQL 服务器上的数据结构是相关的。您可以使用 ADO 动态填充数据表,但这有一些缺点,例如在重新查询/过滤/排序时抛出错误
  • 您已经详细说明了除了您的问题之外的所有内容。请用观察到的错误和预期输出更新您的问题。
  • Float 不是 Decimal(12, 2) 的替代品。应该是金钱/货币
  • 您不只是将数据创建为 SQL Server 视图或结果表,然后将其链接到作为链接表的访问,这是有原因的吗?您的存储过程和直通查询是什么样的?

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


【解决方案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
    

警告:Access 在对数据表表单进行排序和筛选时使用命令文本。如果它包含 Access 的语法错误(因为它是 T-SQL),则在尝试排序/过滤时会出现错误。但是,如果语法有效,但无法执行 SQL(例如,因为您正在使用不再可用的参数),则 Access 将硬崩溃,丢失任何未保存的更改并可能损坏您的数据库。即使您禁用排序/过滤,您仍然可以在尝试排序时触发硬崩溃。您可以在 SQL 中使用 cmets 使语法无效,从而避免这些崩溃。

【讨论】:

  • 优秀的代码和一个非常聪明的想法是通过引用自身来保持表单。 - 但我不确定这是否是现有应用程序上下文中问题/问题的合适解决方案。
  • 好吧,OP 询问 我是否有更好的方法来从 SQL 查询数据并使用 ADO 或替代方法在访问中持久/显示这些数据?。这回答了这个问题:有一种替代(可能更好)的方式,使用 ADO,即我在这里提供的方式
【解决方案2】:

您之前使用了非常古老的原始 ODBC 驱动程序用于 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 之间的转换问题。因此,使用更现代的驱动程序可能会很好地解决这个问题。 - 我不知道它是否能解决你的问题,但这是我会尝试的第一件事。

【讨论】:

  • 据我所知,版本 17 比版本 13 的 ODBC 驱动程序更受欢迎。不过,我对不同的版本不是很了解。您可以获取不同版本的概述和下载here
  • @ErikvonAsmuth:这确实令人困惑。我链接到的 ODBC 驱动程序 13.1 仅在 5 天前发布,并且是最新的。 ODBC 驱动程序 17(2 个月大)是唯一明确支持 SQL-Server 2017 的驱动程序。-我不能说哪个“更好”或“更推荐”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-11
  • 1970-01-01
相关资源
最近更新 更多