Sql 具有计数字段的可更新记录集-MS Access

Sql 具有计数字段的可更新记录集-MS Access,sql,ms-access,Sql,Ms Access,我不是SQL专家。也许我在这里想做的事根本不可能 我试图获得一个可更新的记录集,其中包含一个字段,该字段是聚合函数的结果 我在找这样的东西: SELECT Contact.*, Count(OrderID) as CountOfOrders FROM Contact INNER JOIN Order ON Order.ContactID = Contact.ContactID WHERE ContactID = 1 SHAPE {SELECT ContactID, ContactName

我不是SQL专家。也许我在这里想做的事根本不可能

我试图获得一个可更新的记录集,其中包含一个字段,该字段是聚合函数的结果

我在找这样的东西:

SELECT Contact.*, Count(OrderID) as CountOfOrders
FROM Contact INNER JOIN Order ON Order.ContactID = Contact.ContactID
WHERE ContactID = 1
 SHAPE  {SELECT ContactID, ContactName FROM Contact} 
APPEND ({SELECT ContactID, OrderID FROM Orders} 
         RELATE ContactID TO ContactID
       ) As rsDetails, COUNT(rsDetails.OrderID) AS CountOfOrder

当使用MSDataShape OLE DE提供程序和Jet(或ACE)的OLE DB提供程序时,确实可以创建一个可更新的ADO记录集,并基于一个集合函数(如
COUNT()
)附加一个计算列。生成的SQL风格代码看起来更像这样:

SELECT Contact.*, Count(OrderID) as CountOfOrders
FROM Contact INNER JOIN Order ON Order.ContactID = Contact.ContactID
WHERE ContactID = 1
 SHAPE  {SELECT ContactID, ContactName FROM Contact} 
APPEND ({SELECT ContactID, OrderID FROM Orders} 
         RELATE ContactID TO ContactID
       ) As rsDetails, COUNT(rsDetails.OrderID) AS CountOfOrder
这里有一个简短的“概念证明”:将以下内容粘贴到任何VBA模块中(例如,使用Excel),无需引用,在临时目录中创建一个新的.mdb,创建包含数据的表,以证明记录集是可更新的
ContactName
值已更改,并且记录集已重新打开,以显示它确实已更改:

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

我认为不可能有包含聚合函数的可更新记录集。@HansUp:对于DAO记录集可能不可能,但是对于ADO记录集是可行的。看我的答案:)我显然必须进入数据成形!MSDataShape提供程序是非常有问题和繁琐的。早在2000年早期,我就试图开始使用它,但遇到了各种各样的问题。例如,它是允许更新不可更新的选择的提供程序,因为使用SQL Server它直接进入基表。这可能会严重破坏您的安全,由于所有这些问题,我将其作为一个有用的工具扔掉。MS似乎也做了同样的事情,因为它是ADP和SQL Server之间的主要组件,并且他们已经反对了大约5年。@David-W-Fenton:“这可能会严重破坏您的安全,由于所有这些问题,我把它作为一个有用的工具扔掉了。”从ACE开始,访问团队还将安全性作为一种有用的工具,特别是用户级别的多样性。但说真的,我不相信你的断言:如果MSDataShape确实暴露了一个安全漏洞,那么我们都会知道的。我不认为您想发布代码来证明您的观点,但如果您愿意,可以自由编辑我的答案。您不记得Steve Jorgensen的一系列文章发现ADO绕过安全视图直接访问数据表的方式存在问题吗?我的理解是,ADO使用的功能是由数据形状组件提供的,但那是很久以前的事了,我可能会记错。你对ACE的攻击以及从其中一种文件格式中删除ULS是不值得的,因为这只是一个廉价的尝试,因为这与我所指的问题完全相反。@David-W-Fenton:对不起,我甚至不记得Steve Jorgensen了。最大的问题是,它是否得到了适当的同行评议?打个比方,艾伦·布朗(Alan Browne)曾经说过,臭名昭著的“
DECIMAL
sort bug”会产生各种奇怪的行为,这一点毫无疑问会留在你的脑海中。事实上,大部分是不可生产的,其不良影响没有报道的那么严重(即有偏见)。似乎没人记得我每隔一周就反驳一次。但我并不痛苦:)