Linked Access DB "была изменена другим пользователем"

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

Дизайн базы данных очень низок, поэтому вам придется нести со мной.

В форме "Клиент" есть поле "Customer_ID", которое по умолчанию должно получить следующий доступный идентификатор клиента, но у пользователя есть возможность отменить этот выбор с помощью существующего идентификатора клиента.

Теперь поле Customer_ID не является PK таблицы Customer. Это также не уникально.

Если клиент дважды звонит, чтобы отправить задание, таблица получит две записи, каждая с одной и той же информацией о клиентах и ​​один и тот же идентификатор клиента.

Если пользователь создает новый билет, Access выполняет быстрый поиск следующего доступного идентификатора клиента и заполняет его. Но он не сохраняет запись. Очевидно, проблема: два пользователя редактируют, чтобы отслеживать работу друг друга, чтобы они не обманывали идентификатор клиента.

Итак, я хочу изменить кнопку "новая запись", чтобы сохранить билет сразу после создания нового.

Проблема в том, что когда я тестирую изменение, я получаю: "Эта запись была изменена другим пользователем с момента ее редактирования".

Определенно нет других пользователей в БД. "Другим пользователем", по-видимому, было мое принудительное сохранение.

Любые идеи?

Ответ 1

Посмотрите на связанную таблицу в SQL Server 2000. Имеет ли она поле, содержащее тип данных бит? Access предоставит вам это сообщение об ошибке в сценарии связанных таблиц, если у вас есть поле бит , которое не имеет значения по умолчанию.

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

Ответ 2

Я видел это поведение раньше, и это фиксировало это для меня:

Попробуйте добавить поле TimeStamp в таблицу (просто добавьте это поле и обновите связанные таблицы. Вам не нужно заполнять это поле любыми данными).

Ответ 3

Ошибка, которую вы получаете, обычно происходит, когда:

  • вы редактируете запись в форме и форма грязная (т.е. изменения не сохраняются),

и

  1. вы запускаете код, который использует DAO или ADO для запуска SQL для обновления той же записи.

В Jet, это два "пользователя", потому что это две разные операции редактирования. Базовая таблица была обновлена ​​обновлением SQL, а данные в буфере формы теперь устарели.

Обычным решением является принудительное сохранение перед запуском обновления SQL:

  If Me.Dirty Then
     Me.Dirty = False
  End If
  [run your SQL update here]

Но если вы используете формы для редактирования записи, вам следует делать все обновления в форме, а не прибегать к SQL для обновления.

Ситуацию, которую вы описываете, создавая свою собственную последовательность, должна быть выполнена следующим образом:

  • пользователь нажимает кнопку NEW RECORD.

  • вывести следующее значение последовательности и сохранить его в переменной.

  • вставьте новую запись с этим значением последовательности через SQL INSERT.

4а. если ваша форма привязана ко всем записям в таблице, запросите форму редактирования данных (при условии, что кнопка NEW RECORD находится в форме, где пользователи редактируют данные), и используйте навигацию по закладкам для перехода к новой записи с последовательным значением, которое вы сохранили в переменной на шаге 2.

4b. Если ваша форма не привязана ко всем записям (как это не должно быть, если это хорошо спроектированная база данных), вы просто измените источник записей формы, чтобы загрузить только новую запись.

Другой альтернативой является избежание SQL INSERT и requery (или сброс источника записей) и просто добавление новой записи в существующую форму, установку поля последовательности в новое значение и немедленное сохранение записи.

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

Ответ 4

Это старый вопрос, с которым я столкнулся с Google, поэтому я отправлю свой ответ.

В драйвере ODBC обязательно включите управление версиями строк. Если таблица уже находится в Access, вам придется отбросить ее и повторно связать с исходной таблицей.

Вы должны знать, включено ли управление версиями строк, поскольку Access должен добавить столбец в таблицу с именем xmin.

Ответ 5

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

Ответ 6

У меня также была такая же проблема. Я пытался обновить таблицу, используя Spring MVC и спящий режим. В моем случае столбец версии в таблице содержит значение больше 1 (т.е. 3), однако информация об обновлении в моем запросе обновления имела значение версии 1.

Ответ 7

Наши проблемы состояли в том, что передняя часть доступа пыталась сохранить int (да/нет) в поле бит mssql (0/1). Изменение базы данных mssql для полей int работало как шарм.

Ответ 8

Я только что столкнулся с другой ситуацией, которая порождает эту ошибку. В таблице mysql у меня было два столбца даты, которые первоначально имели значение по умолчанию "0000-00-00". Позже он был изменен на значение по умолчанию NULL, но многие строки сохранили значение "0000-00-00". Мне пришлось вручную reset значения до NULL, чтобы остановить ошибку.

Потребовалось много времени, чтобы выяснить, что вызывало ошибку, HTH кто-то еще.

Ответ 9

Эта ошибка также может быть выбрана, если в таблице SQL Server содержится столбец datetime2 (в моем случае со значением по умолчанию sysdatetime()). Изменение типа данных обратно в datetime по умолчанию current_timestamp останавливает ошибку.