代码之家  ›  专栏  ›  技术社区  ›  S Meaden

如何在从头创建的adodb.recordset上强制主键唯一性?

  •  0
  • S Meaden  · 技术社区  · 6 年前

    我正在使用一个记录集作为获取某些数据的工具。我收到了副本,我很好奇如果试图添加副本,如何让记录集投诉。

    所以,本质上我想创建一个键字段。我找到了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专家知道这个诀窍。

    更新:我在记录集对象上找到了一个支持方法,如果我传入 CursorOptionEnum.adIndex 然后回答错误。也许使用不同的提供者?

    1 回复  |  直到 6 年前
        1
  •  2
  •   Erik A    6 年前

    正如@alesk所指出的,这是不可能实现的。

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

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

    创建一个名为Table1的表,其中有2个字段(ID、主键、字段1、字符串)

    运行以下代码:

    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?