Сбросить начальное число автонумерации

У меня есть приложение VB6/Access, которое иногда сталкивается с проблемой неправильного начального числа поля автонумерации.

Допустим, есть таблица MYTABLE с идентификатором поля автонумерации (это также первичный ключ). Допустим, на данный момент максимальное значение идентификатора равно 1000. Когда приложение вставляет новую запись (значение идентификатора не указано явно), оно по какой-то причине решает, что следующее значение поля автонумерации равно 950 (а не 1001, как должно быть ) — поэтому возникает ошибка нарушения первичного ключа.

Я нашел статью базы знаний, в которой описываются мои симптомы: http://support.microsoft.com/kb/884185< /а> . Короче говоря, они предлагают запустить запрос:

ALTER TABLE MYTABLE ALTER COLUMN ID COUNTER(1001,1)

Когда я пытаюсь это сделать, происходит сбой с «Недопустимым типом данных поля».

Проблема исправляется, если я открываю базу данных в Access и делаю компакт/восстановление, но мне нужно иметь возможность исправлять такие проблемы внутри приложения: оно установлено на пару тысяч ПК по всему миру, и просит людей сжать /repair с доступом не вариант.

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

Любые идеи для решения?


person Incidently    schedule 18.02.2010    source источник
comment
из любопытства вы закрываете таблицу перед запуском ALTER TABLE MYTABLE ALTER COLUMN ID COUNTER(1001,1)?   -  person Todd Main    schedule 19.02.2010
comment
Если код находится внутри Access MDC/ACCDB, используется язык VBA, а не VB6. Просьба уточнить.   -  person Fionnuala    schedule 19.02.2010
comment
@Otaku: Да, конечно. Этот запрос завершается ошибкой как при выполнении внутри Access, так и при выполнении через DAO. Странно вот что: если в Access я удаляю поле автонумерации, а потом создаю точно такое же поле, то запрос работает. Похоже, что есть разные варианты типа автонумерации, но я не могу понять, в чем эта разница.   -  person Incidently    schedule 19.02.2010
comment
@Remou: приложение VB6/Access = приложение, написанное на VB6 с использованием базы данных Access в качестве серверной части.   -  person Incidently    schedule 19.02.2010
comment
Вы не должны сталкиваться с случайными проблемами с семенами. Являются ли системы, на которых работает ваше приложение, полностью исправленной Windows 2000 и новее? Какая версия msjet40.dll работает в системе? Я бы предложил зарегистрировать версию и посмотреть, есть ли там какие-либо проблемы. Что я сделал, так это использовал различные доступные вызовы API и проверяю номер версии и дату/время важной dll, msjetxx.dll, чтобы убедиться, что она соответствует тому, что есть в моей системе. См. страницу «Проверка установки соответствующего пакета обновления Jet» на моем веб-сайте www.granite.ab.ca\access\verifyjetsp.htm   -  person Tony Toews    schedule 20.02.2010
comment
FWIW, я развернул код сброса начальных значений в одном из своих приложений несколько недель назад, потому что я часто импортирую старые данные, поскольку я продолжаю находить их лежащими в архивных файлах. Его нужно перезагрузить обратно в базу данных (кто-то не смог применить RI, так что там много бессмысленных данных, с внешними ключами, указывающими на несуществующие записи, а некоторые из них указывают на неправильные записи, потому что старые данные использовали тот же числовой диапазон — да, беспорядок!), и каждый раз, когда я это делаю, счетчик Autonumber сбрасывается до самого высокого значения, которое было вставлено из архивных данных.   -  person David-W-Fenton    schedule 21.02.2010
comment
Дэвид, хорошо, но в этом есть смысл. Вы импортируете поле автонумерации, поэтому Jet сбросит начальное число до самого высокого импортированного числа, если оно выше текущего значения. Но его не следует сбрасывать на меньшее число.   -  person Tony Toews    schedule 22.02.2010
comment
Он устанавливается на меньшее число, которое является наибольшим числом во вставке. Я сам этого не ожидал, но, поскольку это произошло дважды, я реализовал код сброса начальных значений, чтобы конечные пользователи не увидели ошибку. Я знаю, что это не так, как это должно работать, насколько я понимаю, но я думаю, что каждый раз, когда вы вставляете значение меньше существующего начального числа, это происходит. И в этом случае все эти заархивированные записи имеют более низкие значения, чем существующий Autonumber, и результатом являются коллизии уникальных индексов.   -  person David-W-Fenton    schedule 23.02.2010


Ответы (3)


Пожалуйста, обратитесь к следующей статье, она содержит метод, который вы можете добавить в свой проект доступа для выполнения для сброса заполнения. В прошлом меня несколько раз выручало:

http://allenbrowne.com/ser-40.html

В дополнение к этому он дает объяснение и понимание причин и возможных решений таких проблем.

person Jakkwylde    schedule 18.02.2010
comment
Я бы никогда не добавил ссылку только для поддержки одной функции — позднее связывание было бы гораздо лучшим способом сделать это. Но я не уверен, что вы получите что-то большее, чем то, что вы получите с компактным DAO и сбросом начального значения ALTER TABLE. В любом случае, я не могу представить, чтобы я запускал этот код и не уплотнял его после этого. - person David-W-Fenton; 19.02.2010

Вам также может понадобиться убедиться, что ваша база данных настроена на использование ANSI 92, чтобы COUNTER распознавался как допустимый тип данных.

В Access 2007 перейдите в раздел Параметры доступа, конструкторы объектов, синтаксис совместимости с SQL Server (ANSI 92), чтобы установить это.

person AMW    schedule 18.02.2010
comment
Вы можете выполнить ALTER TABLE с помощью ADO, чтобы не устанавливать режим SQL 92. - person David-W-Fenton; 19.02.2010

Возможно, вы сможете решить проблему с помощью компакта/ремонта:

In Access 2010:  Compact and Repair Database on the Database Tools ribbon.
In Access 2007:  Office Button | Manage.
In earlier versions:  Tools | Database Utilities.
person Pritesh    schedule 28.02.2013