On-line: Andrey, гостей 0. Всего: 1 [подробнее..]
АвторСообщение
Администратор




Пост N: 2123
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 10.10.11 11:14. Заголовок: Как определить неправильный индекс


Предложите алгоритм определения битого индекса

Я пока сделал так:
1 Цикл по всем записям:

for i := 1 to RecCount()
goto i
if ordKeyNo() == 0
// битый ключ
endif
next

2. Сделать go top/go bottom
Если таблица непустая, а результат этих операций bof() или eof(), то индекс битый

Какой способ можно предложить еще ?



Спасибо: 0 
ПрофильЦитата Ответить
Ответов - 12 [только новые]







Пост N: 212
Зарегистрирован: 12.11.06
ссылка на сообщение  Отправлено: 10.10.11 15:06. Заголовок: У меня проверяется т..


У меня проверяется так: (выделю жирным основные моменты)

 

* ---------------------------------------------------------------------------
* Выборочная проверка физической и логической целостности данных пакета.
* Все базы закрываются, а после проверки открываются заново.
STAT PROC pCheck()
LOCA aBas:={ {cDbase,"Wares", {"WarCode"}},;
{cDbase,"Cash_ord", {"CashCode"}},;
{cDbase,"ClearWar", {"Cw_code"}},;
{cDbase,"Invoices", {"InvCode"}},;
{cDbase,"Receipts", {"RecCode"}},;
{cDbase,"Stores", {"Stor_war"}} }
LOCA nI:=0, nJ:=0, lCheck:=TRUE, lExit:=FALSE
LOCA sOp:="9105"
S_PROC
pinStat(sOp,0)

CLOS DATA
SET CURS OFF

FOR nI := 1 TO Len( aBas ) // По базам.
FOR nJ := 1 TO Len( aBas[nI,3] ) // По индексам.
pOpenView( cHelpc, cError, "База данных: "+aBas[nI,2]+" Индекс: "+aBas[nI,3,nJ] )
lCheck := lIndCheck( aBas[nI,1]+aBas[nI,2], aBas[nI,1]+aBas[nI,3,nJ] )
pCloseView()
IF !lCheck
IF !Fyn("Обнаружено разрушение индекса "+aBas[nI,3,nJ]+" в базе "+aBas[nI,2]+". Продолжать?", cError)
lExit := TRUE
ENDI
ENDI
IF lExit THEN EXIT
NEXT nJ
IF lExit THEN EXIT
NEXT nI

// Стираю файл выхода по ошибке.
Ferase("LS_WORKS.DBF")
fErrQuit("Извините, но после этой операции я должна закончить работу!",cMainc)
RETU

* ---------------------------------------------------------------------------
* Функция проверки физической целостности одного индексного файла.
STAT FUNC lIndCheck( cDbf, cNtx )
LOCA nOldSel:=Select(), nInd:=IndexOrd(), nRec:=RecNo()
LOCA nI:=0, lClose:=FALSE, xRes:=NIL, xOld:=NIL, cKey:="", nC:=0

USE (cDbf) INDE (cNtx) SHAR READONLY
IF NetErr() THEN RETU FALSE

// Проверяем целостность порядка индексации.
cKey := IndexKey()
nC := LastRec()

DbGoTop()
xRes := xOld := Eval( &("{||"+cKey+"}") )
nI := 0
DO WHIL !Eof()
IF Inkey() == K_ESC THEN RETU FALSE
pChangeView( zInt(++nI*100/nC) )
xOld := Eval( &("{||"+cKey+"}") )

IF xRes > xOld

DbCloseArea(); RETU FALSE
ENDI
xRes := xOld
DbSkip()
ENDD
DbCloseArea()
RETU TRUE



Спасибо: 0 
ПрофильЦитата Ответить
Администратор




Пост N: 2126
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 10.10.11 16:06. Заголовок: Т.е, проверка заключ..


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

После открытия индекса сразу проверить количество ключей:
if RecCount() > OrdKeyCount()
// bad index
endif

Что можно предложить еще ?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 2159
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 10.10.11 16:32. Заголовок: Pasha пишет: if Rec..


Pasha пишет:

 цитата:
if RecCount() > OrdKeyCount()


Если индекс уникальный это не сработает правильно

Спасибо: 0 
ПрофильЦитата Ответить



Не зарегистрирован
Зарегистрирован: 01.01.70
ссылка на сообщение  Отправлено: 10.10.11 17:34. Заголовок: Проверка индекса


// поиск вычисленных ключей - по всем записям
set order to nind
block := &("{||"+indexkey()+"}")
..
lerr:=.f.
set order to 0
go top
do while !eof()
ckey:= eval(block)
recn:=recno()
set order to nind
dbseek(ckey,.f.)
lerr:=.t.
do while !eof().and.(ckey==eval(block))
if recno()=recn
lerr:=.f.; EXIT
endif
skip
enddo
if lerr// bad index
exit
endif
set order to 0
go recn
skip
enddo
...

Спасибо: 0 
Цитата Ответить
Администратор




Пост N: 2127
Зарегистрирован: 23.05.05
ссылка на сообщение  Отправлено: 10.10.11 19:13. Заголовок: Всем спасибо. В резу..


Всем спасибо. В результате я остановился на примерно таком алгоритме:

Local bKey := &('{||'+IndexKey()+'}') 
Local cFor := OrdFor(), bFor
Local lUniq := ordIsUnique()
Local lBad := .f., i

if ! Empty(cFor)
bFor := &('{||'+cFor+'}')
endif
// быстрая проверка для неуникального индекса
if ! lUniq .and. Empty(cFor) .and. OrdKeyCount() < RecCount()
lBad := .t.
endif

set deleted off
// еще одна быстрая проверка
if ! lBad .and. Empty(cFor) .and. RecCount() > 0
go bottom
if eof()
lBad := .t.
endif
endif

// если не судьба, приходится проверять весь файл:
if ! lBad

for i := 1 to RecCount()
goto i
if Empty(bFor) .or. Eval(bFor)
if ! (Eval(bKey) == OrdKeyVal())
lBad := .t.
exit
endif
elseif OrdKeyVal() != nil
lBad := .t.
exit
endif
next

endif


Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 3727
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 15.11.14 23:28. Заголовок: Вот еще один залет н..


Вот еще один залет на индексе (открываю базу, потом индексный файл) и ошибка вообще не знамо где:


По коду своему без толку лазить, ничего не найдешь.
Вынос мозга и все....

Кому интересно, пример базы и индекс здесь - https://cloud.mail.ru/public/56155cb9fec5/MiniGui-Sample


Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 4269
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 15.11.14 23:55. Заголовок: как обычно накосячил..


как обычно накосячил.

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 3728
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 16.11.14 01:13. Заголовок: Dima пишет: как обы..


Dima пишет:

 цитата:
как обычно накосячил.


Индекс слетел сам, по вылету программы, а потом драйвер DBF открывает его, без обработки на ошибку.
Ну и где я накосячил ?

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 4270
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.11.14 17:17. Заголовок: Andrey Андрей а есл..


Andrey
Андрей а если сделать простую программу без GUI , типа:
открыл базу
затем browse()
будут какие то ошибки или она просто тихо завершится ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 3733
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 16.11.14 18:51. Заголовок: Dima пишет: открыл ..


Dima пишет:

 цитата:
открыл базу
затем browse()
будут какие то ошибки или она просто тихо завершится ?


Пробовал dbedit - все работает без вылета. На экране записей нет и всё. Вылета нет.

Спасибо: 0 
ПрофильЦитата Ответить
администратор




Пост N: 4271
Зарегистрирован: 17.05.05
ссылка на сообщение  Отправлено: 16.11.14 19:12. Заголовок: Andrey пишет: На эк..


Andrey пишет:

 цитата:
На экране записей нет и всё


А по факту записи есть в базе ?

Спасибо: 0 
ПрофильЦитата Ответить
постоянный участник




Пост N: 3734
Зарегистрирован: 12.09.06
ссылка на сообщение  Отправлено: 16.11.14 21:11. Заголовок: Да, есть. Но термина..


Да, есть.
Но терминалка работает, записей нет и все, т.е. прога (терминалка) не вылетает.

Я написал про МиниГуи другим на заметку. Что вылет происходит при "битых" индексах.

Спасибо: 0 
ПрофильЦитата Ответить
Ответ:
1 2 3 4 5 6 7 8 9
большой шрифт малый шрифт надстрочный подстрочный заголовок большой заголовок видео с youtube.com картинка из интернета картинка с компьютера ссылка файл с компьютера русская клавиатура транслитератор  цитата  кавычки моноширинный шрифт моноширинный шрифт горизонтальная линия отступ точка LI бегущая строка оффтопик свернутый текст

показывать это сообщение только модераторам
не делать ссылки активными
Имя, пароль:      зарегистрироваться    
Тему читают:
- участник сейчас на форуме
- участник вне форума
Все даты в формате GMT  3 час. Хитов сегодня: 516
Права: смайлы да, картинки да, шрифты да, голосования нет
аватары да, автозамена ссылок вкл, премодерация откл, правка нет