Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Начинающим";
Текущий архив: 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
2-1277501484
Германн
2010-06-26 01:31
2010.09.26
У TStringGrid отсутствует ScrollBar


2-1278015203
AKE
2010-07-02 00:13
2010.09.26
Как сделать так чтобы элементы StringList...


15-1277833769
bss
2010-06-29 21:49
2010.09.26
Интересный вызов Initialization секции в BPL


6-1218676192
piople
2008-08-14 05:09
2010.09.26
[ISAPI] Проблема ограничения длинны загружамемого контента


3-1245673105
dmitrot
2009-06-22 16:18
2010.09.26
Scroll DBGrid





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский