如何以编程方式创建 SQL Server 视图的 ODBC 链接表并使其可编辑?

2024-02-02

当我使用向导创建到 SQL Server 的 DSN 连接时,我可以将其链接到视图。在这种情况下,Access 将其识别为可编辑表。

但是,如果我使用 vba 代码对视图使用无 DSN 连接(方法 1 来自https://support.microsoft.com/en-us/kb/892490 https://support.microsoft.com/en-us/kb/892490),它被链接为不可更新的表。

我不知道为什么会有差异,但如何连接到 SQL Server 中的视图(作为 Access 中的表或查询)并使其可更新?

编辑:当我使用 SQL Server 中的表而不是视图建立无 DSN 连接时,它可以在 Access 中更新。我猜我的问题与没有唯一 ID 的视图有关,但我很困惑为什么 DSN 连接可以更新,而 DSN-less 则不能。


这并不是因为它没有 DSN,而是因为您是通过 VBA 创建的。如果您通过 Access GUI 链接视图,它会要求您提供主键。

但通过 VBA,它不知道主键,因此链接视图不可更新。对于表,Access 通过 ODBC 自动获取主键,因此表可以工作。

解决方案:通过 VBA 链接视图后设置主键:

S = "CREATE INDEX PrimaryKey ON MyViewName (MyPrimaryKeyField) WITH PRIMARY"
DB.Execute S

如果您有很多视图,并定期重新链接它们(例如从开发数据库到生产数据库),那么对它们的名称和 PK 进行硬编码就变得不切实际。我编写了一个函数来从链接视图中检索所有主键索引,并在链接后重新创建它们。
如果你愿意,我可以挖出来。


Edit:
这就是我所做的:

' This function returns the full DSN-less connect string
Private Function ODBC_String() As String
    ' In the real world there are several constants and variable in there
    ODBC_String = "ODBC;DRIVER={SQL Server};SERVER=aaa;DATABASE=bbb;UID=ccc;PWD=ccc;LANGUAGE=us_english;TRUSTED_CONNECTION=No"
End Function

链接表或视图第一次,我使用这个(strTable是表/视图名称):

DoCmd.TransferDatabase acLink, "ODBC", ODBC_String(), acTable, strTable, strTable, False, True

对于表,主键 (PK) 是自动确定的。对于视图,我使用“访问”对话框窗口来指定 PK,就像我手动链接视图一样。
PK 信息存储在链接视图的 TableDef 对象中,因此我不必在任何地方对其进行硬编码。

为了存储所有链接视图的 PK 信息,我有这个表(为了简单起见,它是 Access 前端中的本地表):

t_LinkedViewPK
    ViewName        Text(100)
    IndexFields     Text(255)

和这个功能。所有视图(和only视图)称为“v_*”,因此我可以按名称列出它们。
我实际上不确定您是否可以从 TableDef 对象确定它是否指向表或视图。

Private Sub StoreViewPKs()

    Dim TD As TableDef
    Dim idx As index
    Dim FD As Field
    Dim RS As Recordset
    Dim S As String

    ' DB is a global Database object, set to CurrentDB
    DB.Execute "Delete * From t_LinkedViewPK"
    Set RS = DB.OpenRecordset("t_LinkedViewPK")

    For Each TD In DB.TableDefs
        If TD.Name Like "v_*" Then
            ' Views must have exactly one index. If not: panic!
            If TD.Indexes.Count <> 1 Then
                MsgBox "View " & TD.Name & " has " & TD.Indexes.Count & " Indizes.", vbCritical
                Stop
            End If

            Set idx = TD.Indexes(0)
            ' Build field list (the index may contain multiple fields)
            S = ""
            For Each FD In idx.Fields
                If S <> "" Then S = S & ", "
                S = S & FD.Name
            Next FD

            RS.AddNew
            RS!ViewName = TD.Name
            RS!IndexFields = S
            RS.Update
        End If
    Next TD

    RS.Close

End Sub

当我更改表或视图结构,或更改源数据库时(这是通过更改输出来完成的)ODBC_String()),我称这个函数为:

Public Function Sql_RefreshTables()

    Dim TD As TableDef
    Dim S As String
    Dim IdxFlds As String

    DB.TableDefs.Refresh

    ' save current Indizes for Views (recreated after .RefreshLink)
    Call StoreViewPKs

    For Each TD In DB.TableDefs
        If Len(TD.Connect) > 0 Then
            If Left(TD.Connect, 5) = "ODBC;" Then

                Debug.Print "Updating " & TD.Name
                TD.Connect = ODBC_String()
                TD.RefreshLink

                ' View?
                If TD.Name Like "v_*" Then
                    IdxFlds = Nz(DLookup("IndexFields", "t_LinkedViewPK", "ViewName = '" & TD.Name & "'"))
                    If IdxFlds = "" Then Stop

                    ' Create PK
                    S = "CREATE INDEX PrimaryKey ON " & TD.Name & " (" & IdxFlds & ") WITH PRIMARY"
                    DB.Execute S
                End If

            End If
        End If
    Next TD

    DB.TableDefs.Refresh

End Function

Note:
代替桌子t_LinkedViewPK,可以使用字典对象。但是在开发这个的过程中,将它作为一个实际的表格非常有用。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何以编程方式创建 SQL Server 视图的 ODBC 链接表并使其可编辑? 的相关文章

  • 获取在任何日期创建的表的列表?

    我遇到了这样的情况 我想查找我在 2012 年 9 月 14 日 2012 年 9 月 14 日 在 sql server 上创建的表 是否有任何查询会列出在此日期创建的这些表 SELECT FROM sys tables WHERE cr
  • 如何拥有引用另一个表的检查约束?

    我在 SQL Server 2008 数据库中有以下表 tblItem 其中有一个ItemID field 好项目 它还有一个 ItemID 字段 并且有一个指向 tblItem 的外键 tblBadItem 它也有一个 ItemID 字段
  • Excel VBA - 添加自定义数字格式

    我有一个在 Excel 外部生成的文件 其中包含许多百分比 所有这些百分比都有一位小数 当导入到 Excel 中时 Excel 会在百分比中添加第二位小数 这似乎是 Excel 中百分比的某种默认格式 它只是添加了一个 0 我想将所有两位小
  • 为什么我的代码会产生错误:该语句没有返回结果集[重复]

    这个问题在这里已经有答案了 我正在从 Microsoft SQL Server Studio 执行以下查询 该查询工作正常并显示结果 SELECT INTO temp table FROM md criteria join WHERE us
  • 在数据库中搜索时忽略空文本框

    此代码能够搜索数据并将其加载到DataGridView基于搜索表单文本框中提供的值 如果我将任何文本框留空 则不会有搜索结果 因为 SQL 查询是用 AND 组合的 如何在搜索 从 SQL 查询或 C 代码 时忽略空文本框 private
  • 如何在 VBA 中声明接受 XlfOper (LPXLOPER) 类型参数的函数?

    我在之前的回答里发现了问题 https stackoverflow com q 19325258 159684一种无需注册即可调用 C xll 中定义的函数的方法 我之前使用 XLW 提供的注册基础结构 并且使用 XlfOper 类型在 V
  • 可以有一个带有可变列的表吗?

    这可能是一个愚蠢的问题 但这里是 是否可以创建一个能够包含具有可变列数和自定义列名称的行的动态表 我浏览过 EAV 建模 但看起来很沉重 现实生活中的例子可能是这样的 假设我有一个客户登记册 但每个客户可能需要输入不同的信息 根据您要输入的
  • 在 SQL Server 2005 中,len() 和 datalength() 有什么区别?

    SQL Server 2005 中的 len 和 datalength 有什么区别 DATALEN 将返回用于存储值的字节数 http msdn microsoft com en us library ms173486 SQL 90 asp
  • 支持 >65k 行的 Excel VBA SQL 驱动程序

    在 Excel 2010 中通过 VBA 查询 Excel 数据时 我遇到一个有趣的问题 我正在使用这些驱动程序连接到 xls 或 xls x m 文件 Sub OpenCon ByRef theConn As Connection ByV
  • 如何在 SQL Server 中不循环更新列?

    出于性能角度的考虑 我只需要删除循环并使用一些联接或其他解决方案来更新 Result 表中的数据并获得循环返回的相同结果 标量函数 CREATE FUNCTION MultiplyerScl a INT b INT RETURNS INT
  • 告诉我 SQL Server 全文搜索器疯了,不是我疯了

    我有一些客户具有用户正在搜索的特定地址 123 通用方式 数据库中有 5 行匹配 ResidentialAddress1 123 GENERIC WAY 123 GENERIC WAY 123 GENERIC WAY 123 GENERIC
  • 使用宏打开受信任文档或启用宏时 Excel 崩溃

    正如标题所示 我无法使用宏打开受信任的文档 Excel 立即崩溃 制作文档的副本允许其打开 因为该副本不受信任 并且我可以检查 VB 编辑器中的宏 但启用宏会导致另一次崩溃 为什么会发生这种情况以及我可以采取什么措施来解决它 我今天遇到了类
  • 如何向 SQL 连接字符串添加自定义属性?

    我想在 SqlServer 连接字符串中添加一些自定义属性 如下所示 Integrated Security SSPI Extended Properties SomeAttr SomeValue Persist Security Info
  • 重用 t-sql 游标的起始位置?

    我正在开发一个在临时表上使用游标的存储过程 我已经阅读了一些关于为什么不需要游标的内容 但在这种情况下我相信我仍然需要使用游标 在我的过程中 我需要遍历表的行两次 声明游标后 已经单步执行临时表并关闭游标 重新打开时游标的位置是否仍保留在表
  • 捕获 Unicode 文本(西里尔文)并将其插入 MS Access 数据库

    我继承了一个旧的 Web 应用程序 该应用程序使用经典 ASP 将表单中收集的数据写入 Access 2007 数据库 现在他们需要它能够收集西里尔字母的输入 我完全不熟悉代码页 字符集 也不熟悉非拉丁字母 我尝试将输入表单页面上的字符集更
  • Access之后我们要做什么? [关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何使用 php 在 sql 查询中转义引号?

    我有一个疑问 sql SELECT CustomerID FROM tblCustomer WHERE EmailAddress addslashes POST username AND Password addslashes POST p
  • 如何修复日期过滤器 VBA,因为它没有拾取我范围内的所有日期

    我正在尝试创建一个过滤器来过滤掉我选择的日期内的所有日期 我选择的日期将始终反映整个月 例如 如果我需要 2019 年 5 月的数据 我将输入开始日期为 01 05 2019 结束日期为 31 05 2019 我的数据过滤器将需要选取经过我
  • 替换字符串中的多个字符,而不使用任何嵌套替换函数

    我的表中存储了一个方程 我一次获取一个方程 并希望将所有运算符替换为任何其他字符 输入字符串 N 100 6858 6858 N 100 0 2 N 35 运算符或模式 替换字符 输出字符串 N 100 6858 6858 N 100 0
  • Access / Word 2010 VBA 邮件合并尝试打开 [文件夹名称].mdb 而不是 ACCDB 源

    我们正在尝试从 Access 中自动执行邮件合并过程 单击按钮后 VBA 将运行指定当前数据库 accdb 作为数据源并运行 SQL 具体代码如下 Set up Word Dim objWord As Object Set objWord

随机推荐