我看了下面的问题,这正是我想要做的事情,但是发布的答案对我来说似乎不起作用。我的查询基本相同,但我会详细说明。
我有一个表格,用以下内容更新信息表:
Forename
Surname
EmailAddress
数据库还会通过字段的默认值设置中的= Date()自动添加DateEntered,并且有一个名为CPDEAID的主键自动编号。
我将以下代码添加到表单。
Private Sub Form_BeforeUpdate(Cancel As Integer)
Set rst = Me.RecordsetClone
rst.FindFirst "[CPDEAID] <> " & Me.CPDEAID & " AND [Forename] = " & Me.Forename & " AND [Surname] = " & Me.Surname & " AND [EmailAddress] = " & Me.EmailAddress
If Not rst.NoMatch Then
Cancel = True
If MsgBox("This person already exists; would you like to go to the existing record?", vbYesNo) = vbYes Then
Me.Undo
DoCmd.SearchForRecord , , acFirst, "[CPDEAID] = " & rst("CPDEAID")
End If
End If
rst.Close
End Sub
但是,这似乎不起作用。我可以让我的数据库不创建重复记录的唯一方法是通过创建一个多列索引 - 但这有点乱,因为我想要一个干净的“用户友好”前端。
我在这里错过了一些非常简单的事情吗?
Prevent Duplicate Records, Query Before Creating New Records
答案 0 :(得分:0)
它可能不起作用,因为在rst.FindFirst
中您构建了一个比较文本列的SQL字符串,但是您不在参数周围使用单引号。
但是你不应该用用户输入这样做,因为这会冒SQL注入的风险。
相反,使用如here所示的参数查询,或在标准模块中使用这样的实用程序函数:
' DLookupPar: Look up a value with a parameterized query
' The first 3 parameters are identical to DLookup, but in Criteria you can use parameters.
' Then add the exact number of parameters as following arguments, in the exact order as used in <Criteria>
'
' Sample call:
' varUserID = DLookupPar("UserID", "tUsers", "Username = [parUser] AND [Password] = [parPassword]", Me!Username, "aPassword")
'
Public Function DLookupPar(Expr As String, Domain As String, Criteria As String, ParamArray arParams() As Variant) As Variant
Dim db As DAO.Database
Dim qd As DAO.QueryDef
Dim rs As DAO.Recordset
Dim strSelect As String
Dim i As Long
strSelect = "SELECT " & Expr & " FROM " & Domain & " WHERE " & Criteria
'Debug.Print strSelect
Set db = CurrentDb
' Create temporary querydef (no name) and set all parameters from arParams
Set qd = db.CreateQueryDef("", strSelect)
For i = LBound(arParams) To UBound(arParams)
qd.Parameters(i) = arParams(i)
Next i
Set rs = qd.OpenRecordset(dbOpenSnapshot)
If Not rs.EOF Then
' Return the first and only column
DLookupPar = rs(0)
Else
DLookupPar = Null
End If
rs.Close
End Function
并在您的表单中使用它:
Dim ID As Long
Dim rs As Recordset
ID = Nz(DLookupPar("CPDEAID", "yourTable", _
"[CPDEAID] <> [parCPDEAID] AND [Forename] = [parForename] AND [Surname] = [parSurname] AND [EmailAddress] = [parEmailAddress]", _
Me.CPDEAID, Me.Forename, Me.Surname, Me.EmailAddress), 0)
If ID > 0 Then
' MsgBox etc
Set rs = Me.RecordsetClone
rs.FindFirst "[CPDEAID] = " & ID
Me.Bookmark = rs.Bookmark
rs.Close
End If