如何在从头开始创建的 ADODB.Recordset 上强制执行主键唯一性?

How to enforce Primary Key Uniqueness on a ADODB.Recordset created from scratch?

我正在使用记录集作为我正在获取的一些数据的载体。我收到了重复项,我很好奇如何让记录集在尝试添加重复项时进行投诉。

所以,基本上我想创建一个关键字段。我找到了 adFldKeyColumn 参数,但没有强制执行,我一定是遗漏了什么。

Function CreateIndexedRecordSet() As ADODB.Recordset
    Dim rs As ADODB.Recordset
    Set rs = New ADODB.Recordset
    rs.Fields.Append "Name", adBSTR, 255
    rs.Fields.Append "pkey", adInteger, , adFldKeyColumn
    rs.Open

    rs.AddNew Array("Name", "pkey"), Array("foo", 1)
    rs.AddNew Array("Name", "pkey"), Array("bar", 1)  '<--- this should complain

    Debug.Print rs.Supports(CursorOptionEnum.adIndex) '<--- sadly prints False, perhaps use a different provider?

    Set CreateIndexedRecordSet = rs
End Function

请不要分类回答,我很清楚我可以在获取数据的同时使用字典并以这种方式捕获重复项,这就是我在此期间要做的。只是必须有知道诀窍的 ADO 专家。

更新:我在 RecordSet 对象上找到了一个 Supports 方法,如果我传入 CursorOptionEnum.adIndex,它会回复 False。也许使用不同的供应商?

这是无法实现的,如@AlexK所述

ADODB 记录集不支持自身约束。强制约束的是数据库,而不是记录集。如果您的记录集没有更新到数据库,则没有任何限制。

要演示此行为,您可以在 Access 中测试以下内容:

创建一个 table 包含 2 个字段(ID、主键、Field1、字符串)的名为 Table1

运行以下代码:

Dim rs As New ADODB.Recordset
Dim conn As ADODB.Connection
Set conn = CurrentProject.Connection
conn.CursorLocation = adUseClient
rs.Open "SELECT * FROM Table1", conn, adOpenKeyset, adLockBatchOptimistic 'Open up recordset
Set rs.ActiveConnection = Nothing 'Disconnect it from the database connection
rs.AddNew Array("ID", "Field1"), Array(1, "A") 'Add a record
rs.AddNew Array("ID", "Field1"), Array(1, "A") 'And another identical one
Set rs.ActiveConnection = conn
'All fine until here, recordset contains 2 records with identical primary key
rs.UpdateBatch 'Errors, duplicate primary key

当然,您可以自己手动检查重复项,或在 Recordset_WillChangeRecord 事件上设置处理程序以强制执行约束,但您说您对此不感兴趣。

无法完成 每个 Is “this is not possible” an acceptable answer?

允许回答