我正在Access 2007中开发一个应用程序。它使用连接到SQL Server 2005后端的.accdb前端。我使用在运行时绑定到ADO记录集的表单。为了提高效率,记录集通常只包含一条记录,并在服务器上查询:
Public Sub SetUpFormRecordset(cn As ADODB.Connection, rstIn As ADODB.Recordset, rstSource As String)
Dim cmd As ADODB.Command
Dim I As Long
Set cmd = New ADODB.Command
cn.Errors.Clear
' Recordsets based on command object Execute method are Read Only!
With cmd
Set .ActiveConnection = cn
.CommandType = adCmdText
.CommandText = rstSource
End With
With rstIn
.CursorType = adOpenKeyset
.LockType = adLockPessimistic 'Check the locktype after opening; optimistic locking is worthless on a bound
End With ' form, and ADO might open optimistically without firing an error!
rstIn.Open cmd, , adOpenKeyset, adLockPessimistic 'This should run the query on the server and return an updatable recordset
With cn
If .Errors.Count <> 0 Then
For Each errADO In .Errors
Call HandleADOErrors(.Errors(I))
I = I + 1
Next errADO
End If
End With
End Sub
rstSource(包含记录集所基于的TSQL的字符串)由调用例程汇编,在本例中是来自绑定表单的Open事件:
Private Sub Form_Open(Cancel As Integer)
Dim rst As ADODB.Recordset
Dim strSource As String, DefaultSource as String
Dim lngID As Long
lngID = Forms!MyParent.CurrentID
strSource = "SELECT TOP (100) PERCENT dbo.Customers.CustomerID, dbo.Customers.LegacyID, dbo.Customers.Active, dbo.Customers.TypeID, dbo.Customers.Category, " & _
"dbo.Customers.Source, dbo.Customers.CustomerName, dbo.Customers.CustAddrID, dbo.Customers.Email, dbo.Customers.TaxExempt, dbo.Customers.SalesTaxCode, " & _
"dbo.Customers.SalesTax2Code, dbo.Customers.CreditLimit, dbo.Customers.CreationDate, dbo.Customers.FirstOrder, dbo.Customers.LastOrder, " & _
"dbo.Customers.nOrders, dbo.Customers.Concurrency, dbo.Customers.LegacyLN, dbo.Addresses.AddrType, dbo.Addresses.AddrLine1, dbo.Addresses.AddrLine2, " & _
"dbo.Addresses.City, dbo.Addresses.State, dbo.Addresses.Country, dbo.Addresses.PostalCode, dbo.Addresses.PhoneLandline, dbo.Addresses.Concurrency " & _
"FROM dbo.Customers INNER JOIN " & _
"dbo.Addresses ON dbo.Customers.CustAddrID = dbo.Addresses.AddrID "
strSource = strSource & "WHERE dbo.Customers.CustomerID= " & lngID
With Me 'Default is Set up for editing one record
If Not Nz(.RecordSource, vbNullString) = vbNullString Then
If .Dirty Then .Dirty = False 'Save any changes on the form
.RecordSource = vbNullString
End If
If rst Is Nothing Then 'Might not be first time through
DefaultSource = .RecordSource
Else
rst.Close
Set rst = Nothing
End If
End With
Set rst = New ADODB.Recordset
Call setupformrecordset(dbconn, rst, strSource) 'dbconn is a global variable
With Me
Set .Recordset = rst
End With
End Sub
从setupformrecordset返回的记录集是完全可更新的,其.Supports属性显示了这一点。它可以在代码中进行编辑和更新。
然而,整个表单是只读的,即使它的.AllowEdits和.AllowAdditions属性都是正确的。即使是右手边的字段(“多边”)也无法编辑。
从TSQL中删除INNER JOIN子句(将strSource限制为一个表)使表单完全可编辑。
我已经验证了TSQL包含来自两个表的priimary密钥字段,每个表都包含一个并发的时间戳字段。
我尝试更改记录集的.CursorType和.CursorLocation属性无效。
我做错了什么?
答案 0 :(得分:1)
我在SQL中遇到了与内部JOIN操作相同的问题。
也许你可以看到这个链接:
http://office.microsoft.com/en-gb/access-help/edit-data-in-a-query-HA010097876.aspx
某些查询无法更新。
所以你解决了这个问题?
答案 1 :(得分:0)
我想你想在记录集上设置Unique Table动态属性。
答案 2 :(得分:0)
我找到的解决方法是使用&#39; IN&#39;条款。例如:
SELECT c.*
FROM CATEGORY c
WHERE c.category_id IN (
SELECT p.category_id
FROM PRODUCT p
JOIN CUST_ORDER o ON o.product_id = p.product_id
WHERE p.product_type = 'Widget'
AND o.units > 50
)
显然,硬编码值可以传递给子程序(并使用绑定变量)。需要注意的重要一点是IN子句可以有任意数量的连接,并且Resultset仍然可以更新。
如果您需要来自多个表的字段,可以尝试创建数据库视图和/或使用DLookup()。