Access db的多用户支持

时间:2014-09-02 21:20:17

标签: access-vba

我所拥有的是一个记录客户和供应商的数据库 3个表格中的地址,tblCustomerstblSupplierstblAddresses使用Access。

如:

[tblCustomers] <== [tblAddresses] ==> [tblSuppliers]

例如,当我输入客户的详细信息后,检查了所有必填字段 我将新记录插入[tblAddresses],然后将客户详细信息插入[tblCustomers] 其中[tblCustomers].AddressFK = [tblAddresses.AddressPK]

问题是我通过选择最新记录获得tblAddresses.AddressPK,但事实并非如此 处理多用户。当2个或更多人同时创建新客户或供应商时  它链接到错误的地址。 e.g。

  1. 创建新客户
  2. 创建供应商
  3. 当(1)和(2)同时保存记录时,它们都在中创建新的地址记录 tblAddresses并且我不知道哪个属于哪个。

    最初,我认为既然客户和供应商共享相同的地址字段 我可以将他们的地址放在同一张桌子上,但现在听起来不错。

    有谁知道如何解决这个问题?

    我对任何事情持开放态度,更糟糕的是我会重新设计数据库。

    PS:我忘了提到我使用的是VBA内置的Access而不是.NET。

    更新:感谢大家的投入,我找到了另一种管理方法。 @@ identity听起来不错,但我还没有使用它(我已经改变了数据输入
    而不是程序)所以我不确定我是否应该将其标记为答案。但是,谢谢,
    我学到了新东西。 ^^

1 个答案:

答案 0 :(得分:0)

@LocTrang:实际上,客户可能拥有多个地址(结算,投放,替代投放)。这种关系看起来像是

  1. [客户] -1:1 ---- 0:m [地址]&gt;没有相应的客户详细信息,客户地址就不可能存在。
  2. 供应商也一样。供应商可能有多个地址(账单,仓库) 供应商和地址表之间的关系看起来与客户与地址相同。

    通常客户和供应商都有自己的地址表,但是如果您想将这两个地址保存在一个表中,您将设计这样的地址表

    1. Address_ID&gt; Primary1
    2. Owner_ID&gt;小学2(*)
    3. Address_type&gt;(可以是来自address_type表的主键)
    4. ADDRESS_LINE1
    5. ADDRESS_LINE2
    6. ......其余的专栏
    7. 此设计可防止数据库中的数据不一致。 (*)但是:要实现这一点,owner_id在整个数据库中必须是唯一的,或者至少在客户和供应商表之间是唯一的。由于customer和supplier表中的Autonumber字段将从1开始,因此您不能将其用作owner_id,因为它在这两个表之间不是唯一的。最好在表格中使用“GUID / uuid”作为unique_id 构建一个自定义唯一字段,例如supplier_ID以“S_”开头,customer_id以C _

      开头

      您可以选择创建另一个名为Address_type的表:

      1. Address_type_id&gt;主键,自动编号
      2. Address_type
      3. 描述
      4. 并将其粘贴到地址表中。

        现在回答你的问题: 如果您使用Access表单输入客户详细信息,则可以创建地址子表单,并通过LinkMasterField和LinkChildField链接主表单和子表单。这样您首先创建客户记录,然后当您移动到新创建的地址子表单时,会为您预先填充customer_Id。 喜欢她:( C_ID是唯一的客户/ owner_id) enter image description here

        使用after insert事件自动更新您的客户唯一ID

        Private Sub Form_AfterInsert()
            Me.txt_c_id.value = "C_" & Me.txt_Customer_id.value
        End Sub
        

        如果您使用VBA输入客户详细信息,请尝试通过交易 封装您的数据执行。这样,无论有多少其他用户创建记录,您始终都是安全的:

        vba代码:

        Private Sub btn_add_new_Click()
            Dim MyDB As DAO.Database
            Dim MyRs As DAO.Recordset
        
            Set MyDB = CurrentDb
        
            Dim Last_ID As Long
        
            Dim SQL_GET As String
            Dim SQL_SET As String
        
            DBEngine.BeginTrans
                On Error GoTo ERROR_TRANS:
                SQL_SET = "INSERT INTO TBL_Customer(C_name,C_contact) VALUES('Second Customer','Second Contact')"
                MyDB.Execute SQL_SET, dbFailOnError
        
                SQL_GET = "SELECT MAX(Customer_id) AS LAST_ID FROM TBl_Customer"
                Set MyRs = MyDB.OpenRecordset(SQL_GET)
                Last_ID = Nz(MyRs("LAST_ID"), 0)
        
                'Since access does not provide triggers we update the customer unique id manually
                If Not Last_ID = 0 Then
                    SQL_SET = "UPDATE TBL_Customer SET C_ID = 'C_" & Last_ID & "' WHERE TBL_Customer.Customer_id = " & Last_ID
                    MyDB.Execute SQL_SET, dbFailOnError
                End If
        
                'Now add the address record via vba
                SQL_SET = "INSERT INTO TBL_Address(Owner_ID, type, Address_line1, Address_line2, city) VALUES('C_" & Last_ID & "','Billing','01 Main Street','Flat 2','London');"
                MyDB.Execute SQL_SET, dbFailOnError
            DBEngine.CommitTrans
        
            MsgBox "Customer inserted. New customer ID = C_" & Last_ID, vbInformation, "Success"
        EXIT_ROUTINE:
            On Error Resume Next
            Set MyDB = Nothing
            Set MyRs = Nothing
            Exit Sub
        ERROR_TRANS:
            On Error Resume Next
            DBEngine.Rollback
            MsgBox "Sorry there was a problem while creating new customer record", vbExclamation, "Unable to insert"
            Err.Clear
            GoTo EXIT_ROUTINE
        End Sub
        

        我希望,你已经理解并会更好地利用这个答案。