Форум: "Начинающим";
Текущий архив: 2010.09.26;
Скачать: [xml.tar.bz2];
ВнизКак исправить поле "счётчик"? (ADO + Access) Найти похожие ветки
← →
_MiK_ (2010-06-26 09:52) [0]Случайным образом, после длительной эксплуатации ADO + Access, в таблице была обнаружена ошибка - поле "счётчик" перестало быть ключевым. Сделать его обратно таковым - не давали несколько повторяющихся чисел. Помогло только удаление этого поля (т.к. исправить номер записи нельзя), и создание его заново.
Как программно:
- обнаружить данную ошибку?
- исправить (переиндексировать) значения данного поля?
← →
sniknik © (2010-06-26 12:03) [1]> поле "счётчик" перестало быть ключевым.
поле "счётчик" и не обязано быть ключевым... просто чаще всего используется в этой связке для суррогатных ключей.
т.что если кто-то(???) поменял структуру таблицы, аксесс(jet) сопротивляться не будет. программисту типа виднее какая ему структура нужна.
> Как программно:
> - обнаружить данную ошибку?
95% системных ошибок сидят в 30-40 см перед монитором...
> - исправить (переиндексировать) значения данного поля?
удалить дубли (или записать новую последовательность, если удалять нельзя), восстановить ключ - alter table ..., установить желаемое значение счетчика - alter table ....
← →
sniknik © (2010-06-26 12:09) [2]> или записать новую последовательность, если удалять нельзя
естественно изменив предварительно тип на простой интежер (alter table ...), и возможно даже не восстанавливать последовательность (если не критично, нет связок на этот ключ) а просто "занилить" все, при смене типа на счетчик оно вроде само считает.
← →
_MiK_ (2010-06-26 12:59) [3]1) на счёт обнаружения ошибки в базе - я думаю самое простое, это проверить является ли первое поле ID в таблице - ключевым? Как это можно проверить программно?
2) благодарю за подсказку! только хотел уточнить:
- меняем тип поля на Integer:
alter table [название таблицы] alter column ID Integer
- очищаем:
Update [название таблицы] Set ID = NULL
Как заполнить поле заново (числами по-порядку)? Какое значение соответствует типу поля "счётчик", чтобы потом из Integer его обратно сметнить? И как его сделать ключевым?
← →
sniknik © (2010-06-26 13:41) [4]> Как заполнить поле заново (числами по-порядку)?
> а просто "занилить" все, при смене типа на счетчик оно вроде само считает.
> Какое значение соответствует типу поля "счётчик"
справочную информацию без проблем можно получить в справке...
> И как его сделать ключевым?
> восстановить ключ - alter table ...
← →
_MiK_ (2010-06-26 15:20) [5]Ок! - спасибо!
А на счёт первого вопроса - является ли первое поле ID ключевым?
Как проверить?
← →
Ega23 © (2010-06-26 15:26) [6]
> является ли первое поле ID ключевым?
Обратиться к INFORMATION_SCHEMA
← →
sniknik © (2010-06-26 16:19) [7]а смысл?
само по себе поле не меняет тип/не становится не ключевым. это сделал ты (твоя программа) судя по неуемному желанию, даже при ошибке, восстанавливать и менять структуру только программно...
и что получится? ты в одном месте программы признак уберешь ("случайным образом случилось"), в другом поставишь и все ссылки на ключ из других таблиц "пойдут лесом" т.к. порядок записей не гарантирован.
не лучше ли найти источник "случайного образа"? вместо того чтобы городить "восстановление" которое убьет весь порядок в базе.
← →
_MiK_ (2010-06-26 20:51) [8]Итак...
1) "Побились" индексы в двух подчинённых таблицах. Их изменение ни на что не влияет (не привязаны ни к чему). Как бьются? - можно только догадываться... м.б. сеть, или одновременное создание двух записей! Поля "счётчики" в них я может бы и не делал, но почитав умные книги - понял, что ключевое поле обязательно должно быть в любой таблице. Или можно без них?
2) Не сработало (или я не правильно делаю):ADOConnection.OpenSchema(siPrimaryKeys, VarArrayOf([Unassigned, Unassigned,
"TablePL"]), EmptyParam, ADODataSetPL);
ADODataSetPL.RecordCount всегда = -1
3) Опусташённый alter column ID Integer => Set ID = NULL делать счётчиком не даёт - пишет, что необходимо создать новое поле. Значит нужно удалять/создавать поле ID? или, как я уже спрашивал - можно перезаполнить Integer и попробовать его сделать AutoInc?
← →
Anatoly Podgoretsky © (2010-06-26 21:45) [9]Можно без ПК, но он обязательно должно быть.
← →
sniknik © (2010-06-26 23:55) [10]> alter column ID Integer => Set ID = NULL
это что за бред? пиши по русски. в смысле в командах sql.
> Значит нужно удалять/создавать поле ID?
как хочешь, но голос разума за то чтобы не трогать структуру базы в процессе эксплуатирования. (коней на переправе не меняют. а если уж и меняют то тщательно взвесив и обдумав все, и уж точно не автоматом в программе)
> можно перезаполнить Integer и попробовать его сделать AutoInc?
можно, попробуй.
проблема только в том, что основное предназначение ПК это однозначная, по нему, идентификация записи... и назначить полностью одинаковым по значениям записям разные ID ты не сможешь, запросом естественно. т.к. при отсутствии ПК идентификация затруднена, и неважно, что это для восстановления ПК и делается.
← →
_MiK_ (2010-06-27 07:22) [11]>пиши по русски. в смысле в командах sql.
Я же написал ранее:
- меняем тип поля на Integer:
alter table [название таблицы] alter column ID Integer
- очищаем:
Update [название таблицы] Set ID = NULL
Всё срабатывает! А вот обратно - в AutoInc не делается (не заполняется автоматом), пишет, что нужно создать новое поле.
>не трогать структуру базы в процессе эксплуатирования
Фактически она остаётся такой, как была. Не могу же я оставить таблицу с битым полем. Вручную помогло только удаление этого поля, и добавление его-же заново (первым, с тем-же именем). Пусть числа (номера) поменялись, как я ранее написал - к ним у меня ничего не привязано, добавлено просто для наличия в таблице ключевого поля - т.к. остальные для этого не подходят (могут повторяться).
Один раз ладно - можно исправить и вручную, но в дальнейшем хотелось бы, чтобы наличие ошибки определялось автоматически, но, к сожалению:
>Не сработало (или я не правильно делаю):
ADOConnection.OpenSchema(siPrimaryKeys, VarArrayOf([Unassigned, Unassigned,
"TablePL"]), EmptyParam, ADODataSetPL);
ADODataSetPL.RecordCount всегда = -1
и автоматически исправлялось.
>назначить полностью одинаковым по значениям записям разные ID ты не сможешь, запросом естественно
Тогда подскажите - как?
← →
sniknik © (2010-06-27 12:00) [12]> но в дальнейшем хотелось бы, чтобы наличие ошибки определялось автоматически
еще раз повторю, это НЕ ОШИБКА, это то как ты спроектировал/сделал структуру изначально, раз уж говоришь не менял ее. использовать можно и так и так, в зависимости от пожелания программиста.
и раз уж сейчас переделал вручную, то такой она и останется.
> и автоматически исправлялось.
вот это, если реализуешь, будет ОШИБКА! т.к. при малейшей неточности ты так исковеркаешь данные, что их невозможно будет восстановить.
> Тогда подскажите - как?
легко. табличными методами jet/dao напрямую.
← →
sniknik © (2010-06-27 12:03) [13]кстати раз получается удалением/созданием поля и на значения тебе плевать, то почему просто это не реализовать да и все?
← →
Anatoly Podgoretsky © (2010-06-27 13:21) [14]> sniknik (27.06.2010 12:03:13) [13]
Ну да, обычно потеря первичного ключа кончается катастрофой, восстановлениею
не подлежит.
← →
_MiK_ (2010-06-29 16:36) [15]Извиняюсь - проблемы с Интернетом!
>это то как ты спроектировал/сделал структуру изначально
Я спроектировал изначально первое поле - счётчик, ключевое! После нескольких сбоев и сжатий/восстановлений обнаружилось описываемое выше. Не было предусмотренно менять структуру таблицы! Более того - где Вы видели поле счётчик, с дублями (двумя одинаковыми номерами)? Если даже захотеть - такое программно ни сделать.
Как исправил? - вручную удалил из битой таблицы (в режиме "Конструктора" таблицы в Access) поле счётчик, переставшее быть ключевым. Затем добавил новое первое поле - ключевое, счётчик. Он спросил что-то вроде: "пронумеровать?" - "да." Всё - ОК! И базой снова стали нормально пользоваться. Номер в поле счётчик меня не волнует - оно мне нужно исключительно для запросов UPDATE. Данное поле ни с какой другой таблицей не связано. Всё работает!
Теперь - как организовать профилактику возникновения таких ошибок? Как их вычислить - я придумал: запросом SELECT + COUNT я проверяю поле "Номер" на наличие дублей. А вот - как исправить? - не придумаю никак.
Основной вопрос - поле счётчик - как описать этот тип в запросе ALTER TABLE? Я выяснил, что это - длинное целое (в access - Long), с дополнениями. Но какими? Как указать в запросе - свойство поля "последовательное"?
И ещё одно - при добавлении поля, в конце запроса пишу - FIRST, поле добавляется, но последним, а не первым, как этго хотелось бы.
← →
sniknik © (2010-06-29 16:58) [16]> Если даже захотеть - такое программно ни сделать.
не шути так
->
CREATE TABLE CountTable (ID Counter, Name VarChar(30))
INSERT INTO CountTable (ID,Name) VALUES (1, "Test")
INSERT INTO CountTable (ID,Name) VALUES (1, "Test")
INSERT INTO CountTable (ID,Name) VALUES (1, "Test")
> поле счётчик, переставшее быть ключевым.
оно не может перестать быть ключевым... сколько раз повторять? и нужно не профилактику делать, а исключать методы приводящие к изменению структуры.
которые у тебя могли быть например тут
> После нескольких сбоев и сжатий/восстановлений
если делал восстановление копированием в другую базу например, или (чем черт не шутит) через mssql (ну да весело, но...) он может сбросить т.к. не всегда обращает внимание на ключи/индексы вроде тоже, не помню, могут "потеряться".
> И ещё одно - при добавлении поля, в конце запроса пишу - FIRST, поле добавляется, но последним, а не первым, как этго хотелось бы.
что за бред?
← →
sniknik © (2010-06-29 17:51) [17]кстати чем можно довести базу access до нескольких восстановлений? у меня за 10 лет работы с больше 10 тыс инсталляций, вспоминается 3 максимум 4 сбоя. а тут с одной базой несколько, чудеса...
← →
Palladin © (2010-06-30 10:17) [18]чудеса в 30-40 см перед монитором )
Страницы: 1 вся ветка
Форум: "Начинающим";
Текущий архив: 2010.09.26;
Скачать: [xml.tar.bz2];
Память: 0.51 MB
Время: 0.004 c