Updateable Recordset with Count Field - MS Access
I'm not an SQL Expert. Maybe what I'm trying to do here isn't even possible.
I'm trying to get an updateable recordset that includes a field that is the result of an aggregate function.
I'm looking for s开发者_C百科omething like this:
SELECT Contact.*, Count(OrderID) as CountOfOrders
FROM Contact INNER JOIN Order ON Order.ContactID = Contact.ContactID
WHERE ContactID = 1
When using the MSDataShape OLE DE provider and the OLE DB provider for Jet (or ACE) then it is indeed possible to create an updateable ADO recordset and APPEND
a computed column based on a set function such as COUNT()
. The resulting SQL-esque code would look more like this:
SHAPE {SELECT ContactID, ContactName FROM Contact}
APPEND ({SELECT ContactID, OrderID FROM Orders}
RELATE ContactID TO ContactID
) As rsDetails, COUNT(rsDetails.OrderID) AS CountOfOrder
Here's a brief 'proof of concept': paste the following into any VBA module (e.g. use Excel), no references required, creates a new .mdb in your temp directory, creates the tables with data, to prove the recordset is updateable the ContactName
value is changed and the recordset reopened to show it has indeed changed:
Sub ShapeAppendCount()
On Error Resume Next
Kill Environ$("temp") & "\DropMe.mdb"
On Error GoTo 0
Dim cat
Set cat = CreateObject("ADOX.Catalog")
With cat
.Create _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
Dim jeng
Set jeng = CreateObject("JRO.JetEngine")
jeng.RefreshCache .ActiveConnection
Set .ActiveConnection = Nothing
End With
Dim con
Set con = CreateObject("ADODB.Connection")
With con
.ConnectionString = _
"Provider=MSDataShape;" & _
"Data Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & _
Environ$("temp") & "\DropMe.mdb"
.CursorLocation = 3
.Open
.Execute _
"CREATE TABLE Contact (" & _
"ContactID INTEGER NOT NULL UNIQUE, " & _
"ContactName VARCHAR(20) NOT NULL);"
.Execute _
"CREATE TABLE Orders (" & _
"ContactID INTEGER NOT NULL REFERENCES Contact (ContactID), " & _
"OrderID INTEGER NOT NULL UNIQUE);"
.Execute _
"INSERT INTO Contact (ContactID, ContactName)" & _
" VALUES (1, 'OneDayWhen');"
.Execute _
"INSERT INTO Orders (ContactID, OrderID)" & _
" VALUES (1, 1);"
.Execute _
"INSERT INTO Orders (ContactID, OrderID)" & _
" VALUES (1, 2);"
Dim rs
Set rs = CreateObject("ADODB.Recordset")
With rs
.CursorType = 2 ' adOpenDynamic
.LockType = 4 ' adLockBatchOptimistic
.Source = _
" SHAPE {SELECT ContactID, ContactName FROM Contact} " & _
"APPEND ({SELECT ContactID, OrderID FROM Orders} " & _
"RELATE ContactID TO ContactID) As rsDetails, " & _
" COUNT(rsDetails.OrderID) AS CountOfOrder"
Set .ActiveConnection = con
.Open
.Fields("ContactName").Value = "Pink Cat"
.UpdateBatch
MsgBox .GetString
.Close
End With
With rs
.Source = _
"SELECT ContactID, ContactName FROM Contact"
Set .ActiveConnection = con
.Open
MsgBox .GetString
.Close
End With
End With
End Sub
精彩评论