#sql #ms-access #vbscript
#sql #ms-access #vbscript
Вопрос:
Используя MS Access, я попытался запустить инструкцию SQL, но я не могу заставить ее работать в случае, если в таблице еще нет записей. Буду признателен за помощь! Спасибо!
Public Function GetReferenceID(RefCode As String) As Integer
Dim RefID As Integer
Dim rec As Recordset
Call connectDB
sSQL = "select RefID from Exceptions where RefCode = '" amp; RefCode amp; "'"
Set rec = CurrentDb.OpenRecordset(sSQL)
If (Not rec.EOF And Not rec.BOF) Then
RefID = rec.RecordCount 1
Else
RefID = 1
End If
GetReferenceID = RefID
End Function
Private Sub RefCode_Change()
Dim tr As Transactions, rID As Integer
Set tr = New Transactions
tr.GetReferenceID (RefCode.Value)
end sub
ОБНОВЛЕНИЕ! В этой строке ошибка (ошибка времени выполнения 3464, «Несоответствие типа данных в выражении критериев«):
Set rec = CurrentDb.OpenRecordset(sSQL)
…в этом коде:
Private Sub RefCode_Change()
Dim rec As Recordset, RefID As Integer
sSQL = "select RefID from Exceptions where RefCode = '" amp; RefCode.Value amp; "'"
Set rec = CurrentDb.OpenRecordset(sSQL)
If (rec.EOF And rec.BOF) Then
RefID = 1
Else
rec.MoveFirst
RefID = rec.RecordCount 1
End If
End Sub
Комментарии:
1. Используйте параметризованный SQL, чтобы избежать атак с использованием SQL-инъекций. Что, если кто-нибудь отправит вам рефкод «‘;исключения из таблицы удаления;—«?
2. Если кто-то отправит ему рефкод «‘;исключения из таблицы удаления;», Access’ database engine не выполнит удаление таблицы.
3. @HansUp: попробуйте это: Используйте параметризованный SQL, чтобы избежать ошибок (например, при повторном коде. Значение содержит одинарную кавычку) и чтобы избежать внедрения
WHERE
предложения SQL в Access (например, что, если кто-то отправит вам рефкод' OR '' = '
— ?4. @Ali: вы, кажется, предполагаете, что RefID будет идеальной последовательностью, т. Е. что MAX (RefID) = COUNT (*), MIN (RefID) = 1, без пробелов и т.д. Держу пари, у вас нет ограничений на эту таблицу, чтобы гарантировать, что ваши предположения всегда будут верны. Но вместо того, чтобы добавлять эти ограничения, я настоятельно рекомендую вам вместо этого использовать другой подход к генерации идентификаторов.
5. @onedaywhen Просто для ясности, я не спорил с параметрами. Моя точка зрения заключалась просто в том, что «; отбросьте трабл … » не представляет опасности для ядра базы данных Access.
Ответ №1:
Я думаю, вы хотите это сделать…
If (rec.EOF And rec.BOF) Then
'empty recordset
RefID = 1
Else
'at least one row
rec.movefirst
RefID = rec.RecordCount 1
End If
Вы также могли бы упростить все это до
RefID = Dcount("*","Exceptions","refCode='" amp; RefCode amp; "'") 1
Комментарии:
1. Refcode — это строковое поле. Вы знаете, как я должен это исправить?
Ответ №2:
Я не совсем уверен, в чем проблема, но я вижу две потенциальные проблемы:
-
вы не указали объявление вашего набора записей, поэтому вы можете столкнуться с неоднозначностью между типами наборов записей DAO и ADO. Вместо этого объявите свою переменную набора записей как
Dim rs As DAO.Recordset
илиDim rs As ADOX.Recordset
(я думаю, что последнее правильно — я никогда не использую ADO, поэтому никогда не нужно указывать это!). Тот факт, чтоSet rec = CurrentDb.OpenRecordset(sSQL)
возвращает несоответствие типов данных, убедительно наводит меня на мысль, что вы объявили набор записей ADO, потому что это вызвало бы несоответствие с набором записей DAO, возвращаемым CurrentDb.OpenRecordset(). -
Наборы записей DAO не могут гарантированно возвращать точное количество записей, пока вы не пройдете весь набор записей. Благодаря технологии Rushmore от Jet / ACE начало набора записей доставляется, в то время как его конец все еще извлекается. Вы могли бы подождать некоторое время и надеяться, что количество записей точное, или вы можете явно создать rs.MoveLast, и в этом случае количество записей будет гарантированно точным.