gpt4 book ai didi

sql-server - 如何以编程方式创建 ODBC 链接表到 SQL Server View 并使其可编辑?

转载 作者:行者123 更新时间:2023-11-29 13:52:15 25 4
gpt4 key购买 nike

当我使用向导创建到 SQL Server 的 DSN 连接时,我能够将它链接到一个 View 。在这种情况下,Access 将其识别为可编辑的表格。

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

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

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

最佳答案

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

但是通过 VBA,它不知道主键,所以链接 View 不可更新。对于表,Access 会通过 ODBC 自动获取主键,因此表可以正常工作。

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

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

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


编辑:
这就是我所做的:

' 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

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

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

对于表,主键 (PK) 是自动确定的。对于 View ,我获取 Access 对话框窗口以指定 PK,就像我手动链接 View 一样。
PK 信息存储在链接 View 的 TableDef 对象中,因此我永远不必在任何地方对其进行硬编码。

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

t_LinkedViewPK
ViewName Text(100)
IndexFields Text(255)

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

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

当我更改表或 View 结构,或更改源数据库时(这是通过更改 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

注意:
可以使用字典对象代替表 t_LinkedViewPK。但是在开发它时,将其作为实际表格非常有用。

关于sql-server - 如何以编程方式创建 ODBC 链接表到 SQL Server View 并使其可编辑?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38895999/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com