DAO.Recordset.Update приводит к блокировке reckord - PullRequest
3 голосов
/ 01 ноября 2011

Я пытаюсь запустить следующий код для обхода набора записей и обновления там, где это необходимо.

У меня есть база данных Microsoft Access, подключенная к бэкэнду MySql.Всякий раз, когда я запускаю этот код, я получаю следующую ошибку:

3197: ядро ​​базы данных Microsoft Office Access остановило процесс, поскольку вы и другой пользователь пытаетесь изменить одни и те же данные одновременно.

Код ниже:

Private Sub test()
    Dim rs As DAO.Recordset, rsCnt As Long, i As Long

    Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
    rs.MoveLast
    rsCnt = rs.RecordCount
    rs.MoveFirst
    For i = 1 To rsCnt
        rs.Edit
        rs!MyFieldInTable = "test"
        rs.Update
    Next i
End Sub

Я думал, что база данных Access может быть повреждена, поэтому я сделал более раннюю резервную копию, но она делает то же самое, что заставляет меня думать, что это проблема MySql.

Мы используем идентичный фрагмент кода в другой версии этой базы данных, связанной с другой таблицей MySql, и она отлично работает.

Кроме того, когда я открываю запрос, набор записей основан наЯ могу без проблем редактировать данные в запросе.

Просто добавьте, в первом цикле, rs! MyFieldInTable обновляется, затем я получаю сообщение об ошибке.

Ответы [ 8 ]

4 голосов
/ 01 ноября 2011

Не похоже, что вы переходите к другой записи в наборе записей.Простое увеличение i не приводит к следующей записи.Более традиционный подход состоит в том, чтобы перебирать набор записей без необходимости использования других переменных (i и rsCnt).

Dim rs as DAO.Recordset
Set rs = CurrentDb.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
rs.moveFirst
Do Until rs.EOF
    rs.Edit
    rs!FieldNameHere = "test"
    rs.Update
    rs.MoveNext
Loop

EDIT После небольшого поиска янаткнулся на эту ветку которая похоже на вашу проблему.В нижней части цепочки предлагается изменить настройки ODBC для вашего MySQL DSN, выбрав вкладку «Дополнительно» и выбрав «Вернуть совпадающие строки».В посте также говорится, чтобы удалить связанную таблицу, а затем повторно связать ее с вашей базой данных Access.Я не использовал Access с MySQL в прошлом, поэтому я понятия не имею, будет ли это работать или нет, поэтому будьте осторожны!

Вы также можете попробовать изменить свой набор записей, чтобы использовать флаг dbOptimistic для набора записейопция блокировки, чтобы увидеть, помогает ли это вообще:

set rs = CurrentDB.OpenRecordSet("qryMyQuery", DB_OPEN_DYNASET, dbOptimistic)

2 голосов
/ 27 апреля 2018

У меня была такая же проблема, и мое решение оказалось значением по умолчанию для полей BIT (1). Доступ не любит, чтобы они были нулевыми. Убедитесь, что вы используете 0 или 1 в mysql для этих полей.

2 голосов
/ 01 ноября 2011

Две вещи, которые вы можете попробовать.Во-первых, попробуйте добавить параметр dbSeeChanges при открытии набора записей:

Dim rs as DAO.Recordset, db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryMyQuery", dbOpenDynaset, dbSeeChanges)
Do Until rs.EOF
    rs.Edit
    rs!FieldNameHere = "test"
    rs.Update
    rs.MoveNext
Loop

Другой вариант, как предложил @HansUp, заключается в использовании оператора обновления SQL вместо динамического набора записей.Ключом здесь является открытие набора записей в виде моментального снимка, чтобы изменения, вносимые в записи, не влияли на сам набор записей.

Dim rs as DAO.Recordset, db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryBatchPayments", dbOpenSnapshot)
Do Until rs.EOF
    db.Execute "UPDATE Payments " & _
               "SET DCReference='test' " & _
               "WHERE PaymentID=" & !PaymentID, dbFailOnError
    rs.MoveNext
Loop
1 голос
/ 01 ноября 2011

Попробуйте вызвать OpenRecordset из объектной переменной, установленной в CurrentDb (), а не напрямую из CurrentDb ().

Dim rs as DAO.Recordset
Dim db As DAO.Database
Set db = Currentdb
Set rs = db.OpenRecordset("qryMyQuery", DB_OPEN_DYNASET)
rs.moveFirst
Do Until rs.EOF
    rs.Edit
    rs!FieldNameHere = "test"
    rs.Update
    rs.MoveNext
Loop

Причина этого предложения заключается в том, что я обнаружил, что операции с CurrentDb напрямую могут вызватьошибка о "блок не установлен".Но я не получаю ошибку при использовании объектной переменной.И ISTR OpenRecordset была одной из таких операций, в которой возникла такая проблема.

Кроме того, у меня сложилось впечатление, что ваш подход - это громоздкий способ достижения эквивалента:

UPDATE qryMyQuery SET FieldNameHere = "test";

Однако я подозреваю, чтоПримером является прокси для реальной ситуации, когда подход с набором записей полезен.Тем не менее это заставляет меня задуматься о том, увидите ли вы ту же или другую ошибку при выполнении оператора UPDATE.

Если у вас по-прежнему возникают проблемы с этим, это может помочь показать нам представление SQL для qryMyQuery.

1 голос
/ 01 ноября 2011

У меня нет MySQL здесь, чтобы попробовать это, но мне кажется, что ваш код не продвигает набор записей после выполнения метода rs.Update, так что вы пытаетесь обновить то же поле в самая жесткая запись.

Добавьте эту строку после rs.Update:

rs.MoveNext

Надеюсь, это поможет.

0 голосов
/ 12 февраля 2015

У меня тоже была такая же проблема; я решил их добавить их в код, используя dao.recordset:

**rst.lockedits = true**
rst.edit
rst.fields(...).value = 1 / rst!... = 1
rst.update
**rst.lockedits = false**

это кажется исправлением конфликта между только что открытыми данными (например, в форме) и обновлением их с помощью кода.

Извините за мой плохой английский ... Я много читал, но никогда не учил его! Я просто итальянец.

0 голосов
/ 29 декабря 2012

Мой маленький полезный совет: биты - это очень, очень, очень плохие типы данных, которые нужно использовать при связывании таблиц SQL с Microsoft Access, потому что только SQL Server понимает, что такое бит, Microsoft Access с трудом интерпретирует, что такое бит. Измените любые типы данных битов на int (целые числа) и перекомпоновайте таблицы, которые должны прояснить ситуацию. Кроме того, убедитесь, что ваши логические значения всегда содержат 1 или 0 (не да / нет или истина / фальшивка) в вашем коде VBA, иначе ваши обновления не будут связаны со связанными таблицами SQL, поскольку Microsoft Access попытается обновить их с помощью True / False или да / нет и SQL не понравится.

0 голосов
/ 21 мая 2012

Я обнаружил, что если попытаться сохранить данные, которые совпадают с данными, уже содержащимися в записи MySql, Access отобразит этот тип ошибки.Я пробовал некоторые предложения из этой темы, но не помогло.

Простым решением для этого является сохранение слегка отличающихся данных с помощью ручной отметки времени.Вот пример заполнения поля порядка сортировки и установки его в 10, 20, 30 ...

    i = 10
    timeStamp = Now()
    Do Until Employee.EOF
        Employee.Edit
        Employee!SortOrderDefault = i
        Employee!LastUpdated = timeStamp
        Employee.Update
        i = i + 10
        Employee.MoveNext
    Loop

Я пробовал автоматическую отметку времени в таблице MySql, но не помогло, когда новыйвходные данные такие же, как и у старых.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...