Access иногда переходит к существующей записи при сохранении новой записи - Access2k FE / SQL2005 BE - PullRequest
12 голосов
/ 15 сентября 2009

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

У меня есть база данных Access, куда я недавно перенес таблицы на SQL 2005. Access продолжает функционировать для пользователей как интерфейс, предоставляющий формы, отчеты и запросы.

Однако после перехода к настройке Access FE / SQL BE пользователи сообщают, что иногда , когда они вводят новую запись, они щелкают в подчиненной форме (сохраняя запись) или нажимают сохранить в самом меню, он переходит к существующей записи. Новая запись была сохранена, но по какой-то причине доступ переключается на другую запись при обновлении. Затем пользователь должен закрыть, найти сохраненную запись и продолжить ее редактирование.

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

Это странное поведение происходит только при вставке новой записи, но не при редактировании существующей записи. Пользователи говорят мне, что это происходит « чаще », когда они собираются добавить новую (цитата, клиент, что угодно) после открытия базы данных.

Я заметил, что это происходит только в формах, которые имеют подчиненные формы, поэтому я сначала подумал, что это связано с отправкой Access через данные подчиненной формы перед сохранением данных формы, что вызывает нарушение PK. Но, похоже, этого не происходит: на сервере SQL нет ошибок, и запись успешно сохранена. Принудительное сохранение пользователями основной записи формы перед добавлением записей подчиненной формы (т. Е. В цитате, принуждение их сохранять цитату до того, как они смогут добавлять позиции) не сработало, это просто вызывает скачок (иногда) при сохранении.

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

Сервер, на котором работают таблицы, - это SQL Server 2005, пользователи используют сочетание Access 2000 и 2003, в основном XP SP3 с парой старых Win2k-блоков. Они используют репликацию слиянием, и несколько пользователей используют реплицированные выпуски SSEE2005 и подписываются на главный сервер. Большинство пользователей не реплицируются, просто подключаются напрямую к серверу через ODBC или собственные подключения клиента SQL. Но я убедился, что это происходит со всеми пользователями, обычно один или два раза в день, и это случилось со мной раньше. Так что это не проблема пользователя.

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

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

Обновление: (1/10/09) Проблема решена, благодаря Дэвиду Фентону. Установка формы в режим ввода данных (Form.DataEntry = true) перед ее открытием для добавления записей действительно предотвращает переход. Клиент не сообщает о каких-либо проблемах, так как я изменил это неделю назад.

Ответы [ 7 ]

8 голосов
/ 15 сентября 2009

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

Я сообщил нескольким контактам в группе продуктов Microsoft Access, а также моим коллегам по Microsoft Access и SQL Server MVP.

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

Кстати, отличная диагностика и подробное описание проблемы.

4 голосов
/ 15 сентября 2009

Это определенно звучит как проблема с блокировкой записи. Вы используете автономные номера в качестве ПК? Пробовали ли вы на 2 компьютерах добавлять записи в одну и ту же форму одновременно (то есть один из них запустит событие вставки, в то время как другой добавил новую запись в форму, но все еще редактирует ее)?

Не могли бы вы так или иначе проверить, если PK вставленной записи после вставки в таблицу остается похожим на PK, указанный перед вставкой (добавив, например, несколько 'debug.print's to ваш код)?

Сценарий может состоять из двух ожидающих вставок, выданных машиной для одного и того же ПК, причем вторая автоматически заменяется во время вставки, в результате чего ваша форма теряет «активную» запись.

3 голосов
/ 16 сентября 2009

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

То есть я не верю в использовании той же формы для редактирования записей, которая используется для их создания.

Вместо этого я использую несвязанный диалог, чтобы собрать все обязательные поля, вставить запись в SQL, а затем открыть основную форму редактирования для этой отдельной записи (а не форму со всей таблицей, перемещенной к только что добавленной записи) .

Имейте в виду, что в сценарии основной формы / подчиненной формы запись в подчиненной форме, когда родительская форма не сохранена, приводит к сохранению родительской записи. Возможно, вы захотите проверить, есть ли в событиях вставки и обновления основной формы какой-либо код, который мог бы вызвать запрос главной формы при вставке новой записи (вызванной редактированием подчиненной формы).

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

1 голос
/ 26 октября 2010

Это ошибка в Access и SQL-коммуникации. Access получает идентификацию новой записи из @@ IDENTITY, а когда вы заканчиваете вводить запись, она перезагружает данные на основе значения из @@ IDENTITY из SQL. В SQL 200 вставлен триггер слияния и доступ обычно работает нормально. Из SQL 2005 триггер слияния имеет некоторую часть, в которой данные вводятся в некоторую таблицу репликации слиянием, которая имеет идентичность и изменяет значение формы @IDDENTITY по сравнению с вновь введенным rcord из Access.

Одним из решений является изменение всего простого триггера вставки для сохранения @IDDENTITY при начале его в переменной и в конце триггера вставки фиктивной записи в таблицу #temp в качестве столбца идентификаторов с сохраненным ранее начальным значением переменной.

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

Я использую это для решения проблемы (где-то в сети).

в начале триггера вставки слияния

ОБЪЯВИТЬ @identity int

ОБЪЯВИТЬ @strsql varchar (128)

set @identity = @@ IDENTITY

и в конце триггера вставки слияния

установить @ strsql = 'выбрать идентификатор (int,' + CAST (@identity как varchar (15)) + ', 1) как идентификатор в # temp'

Exec (@strsql) * * 1 021

последний код должен быть расположен на месте / * вставить конец на этом месте * / в коде репликации слиянием

если @@ error <> 0

goto FAILURE

/ * вставить конец на этом месте * /

Возвращение

Но я ищу способ сделать это автоматически для всех существующих триггеров слияния при публикации и всех существующих триггеров слияния в существующих и будущих подписках.

1 голос
/ 25 октября 2010

Эта проблема вызвана триггером репликации слиянием. В этом триггере (эта проблема характерна для сервера sql 2005, в SQL 2000 server это не проблема Nake) репликация вставляет некоторые данные в таблицы репликации с идентификаторами и получает доступ, получая это число идентификаторов вместо вставки идентификатора реальной формы. Я прочитал, что доступ использует @@ IDENTITY вставку из SCOPE_IDENTITY, и это проблема. Чтобы избежать этого, вы должны изменить триггер слияния таким образом, чтобы в начале триггера вставки вы сохраняли текущее значение из @@ identity в переменной, а в конце триггера вставляли значение во временную таблицу как тождество с начальным значением того, что записано в переменной. это исправит @@ iddentity, и доступ получит правильное значение.

в начале триггера ОБЪЯВЛЯЙТЕ @identity int ОБЪЯВИТЬ @strsql varchar (128) установить @identity = @@ IDENTITY конец что-то вроде установить @ strsql = 'выбрать идентификатор (int,' + CAST (@identity как varchar (15)) + ', 1) как идентификатор в #temp' Exec (@strsql) эт и он должен быть помещен между если @@ error <> 0 goto FAILURE
а также вернуться

Проблема доступа будет устранена не только в форме, но и непосредственно в таблице ссылок ODBC.

Я ищу способ как добавить это автоматически для триггера репликации слияния (в основном, вставки).

1 голос
/ 15 сентября 2009

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

0 голосов
/ 26 октября 2010

0Я нашел это

http://jagbarcelo.blogspot.com/search/label/identity

но я не знаю, могу ли я использовать его в SQL 2008.

...