Форум » Clipper » Странные ошибки ! » Ответить

Странные ошибки !

Виталий: Не стого ни с сего возникают непредсказуемые ошибки при компиляции кода . Траблы заключаются в том что компилятор выкидывает на совершенно нормальных строках ошибки вроде неправильного синтаксиса и т д . Странно - но куски кода уже не менялись там несколько лет . Собственно что-то в модуле правлю - но не там где ошибка .... Выгружаю из памяти NG.EXE - и всё становится нормально . Код ЕХЕшника уже под 1 мег . Блинкер 7 CLIPPER 5.3 .... Что скажут ГУРУ ? Следующая ошибка - уже видно где-то я недосмотрел или не дочитал : Есть индекс CDX и вот иногда (пока не выяснил) выскакивает что-то вроде - "повреждены данные" .... это когда пытаюсь изненить какое-то поле - например логическое значение ...

Ответов - 51, стр: 1 2 3 All

Dima: Основной памяти не хватает для компиляции при загруженном NG скорее всего. Юзай weg - Expert Guide. Norton Guide Reader For Windows http://www.davep.org/norton-guides/ http://www.davep.org/norton-guides/WEGSetup.exe

Pager: Это ерунда! Вот когда начнет писать memory overbloker, тогда придеться помучиться: дробить PRG, уменьшать количество definoв, задавать rmakeу дополнительные параметры /XS /XW....

saulius: ... или отправиться к xHarbour, как Patric Виталий, "повреждены данные": подробнее: система, сеть, среда...


Виталий: saulius Могу скинуть на мыло кусочек кода с описанием - может поможешь ? А ошибка - _DBFCDX/8006 - Обнаружено разрушение данных . Вкратце : && Так я организую индексный файл USE "JROPT" ALIAS "LANJROPT" && Открыли журнал ОПТОВЫХ ПРОДАЖ INDEX ON CODE TAG CODE TO ("LANJROPT") FOR !DELETED() && код товара INDEX ON DATEP TAG DATEP TO ("LANJROPT") FOR !DELETED() && дата продажи INDEX ON OPTCODE TAG OPTCODE TO ("LANJROPT") FOR !DELETED() && код оптовика INDEX ON DATEP TAG DATEPU TO ("LANJROPT") FOR !DELETED() UNIQUE && все даты продаж (для быстрого меню ДАТЫ) INDEX ON OPL TAG OPL TO ("LANJROPT") FOR !DELETED() && Олачено/нет INDEX ON STR(OPTCODE,5,0)+DTOC(DATEP) TAG DPROD TO ("LANJROPT") FOR !DELETED() UNIQUE && все уникальные даты для каждого клиента - для меню КЛИЕНТ->ДАТА INDEX ON X_KASSE TAG XKASSE TO ("LANJROPT") FOR !DELETED() && номера кассовых чеков INDEX ON OPTCODE TAG OPTNEOPL TO ("LANJROPT") FOR (!DELETED() .AND. !OPL ) && по кодам клиентов только НЕОПЛАЧЕННОГО ТОВАРА SET INDEX TO ("LANJROPT") ********************************** && Убиваю стандартный обработчик ошибок bErrorHandler:={|oError| MyError(oError) } bLastHandler:=ERRORBLOCK(bErrorHandler) SELECT TABLE && Тут у нас список товара на оплату && CODE:N:6 - код товара && DAT:D:8 - дата продажи GO TOP DO WHILE !EOF() && пробегаем по списку на оплату S_C:=CODE && Код товара S_D:=DAT && Дата SELECT LANJROPT SET ORDER TO SET ORDER TO TAG OPTCODE && На индекс КЛИЕНТЫ SET SCOPE TO (KLIENT) && Видим только нужного GO TOP DO WHILE !EOF() && Пробегаем по данным нашему клиенту && МЕТКА-1 IF DATEP=S_D .AND. CODE=S_C .AND. !OPL .AND. OPTCODE=KLIENT && товар соответствует ?? RLOCK() NEOPL:=(KOL*CENA)-SUMOPL && Неоплаченная сумма для этой детали XX:=OST_DEN-NEOPL IF XX<0 && Денег на оплату меньше, чем нужно REPLACE LANJROPT->OPL WITH .F. && признак что не до конца оплачен REPLACE DOPL WITH DATE() && дата оплаты REPLACE SUMOPL WITH SUMOPL+OST_DEN && прибавляем денюжки к тому что уже могло быть New_OPL:=New_OPL+OST_DEN && Сумма уже разнесенная OST_DEN:=0 && Нет больше денег DBUNLOCK() ELSE && Денег на оплату этой позиции хватает && Проверяем нужно-ли оплачивать полностью или нет REPLACE DOPL WITH DATE() && Дата оплаты DOB:=(KOL*CENA)-SUMOPL && Добавленная сумма REPLACE SUMOPL WITH SUMOPL+DOB OST_DEN:=OST_DEN-DOB && Уменьшим остаток денег на сумму добавленных денег New_OPL:=NEW_OPL+DOB && Добавили сумму на сумму добавленных денег && МЕТКА-2 REPLACE LANJROPT->OPL WITH .T. && Признак что эта позиция оплачена полностью ENDIF EXIT && раз этот товар проплатили && значит нефиг искать дальше ENDIF SELECT LANJROPT && Ищем дальше SKIP ENDDO SELECT TABLE && Следующая деталька на оплату SKIP ENDDO ************************* вот тут если в алиасе LANJROPT сделать какие-либо движения (SKIP,GO TOP , DBCLOSEAREA()...) - возникает ошибка : _DBFCDX/8006 Обнаружено разрушение данных:OPL Я предполагаю что когда вошли в оплату (МЕТКА-1) по условию : !OPL - тоесть признак что товар не оплачен - а затем в теле делаем изменение этого флага (МЕТКА-2) и вываливается .

Dima: Pager пишет: Это ерунда! тогда как это объяснить ? Виталий пишет: Выгружаю из памяти NG.EXE - и всё становится нормально

Виталий: Видать что-то там в памяти мешает - может переменные какие "накладываются" ? Но это ошибки скорее системные . Меня интересует тема - как убрать [ОШИБКА _DBFCDX/8006 ]?

SergeJa: 1. после создания CDX ОБЯЗАТЕЛЬНО закрыть DBF - это относится ко всем CDX-драйверам 2. CDX в 5.3 кривые. лучше пользовать 5.2e + Six (или xHarbour)

Виталий: Попробую - но вроде я так и делаю ! Дело в том что создание индекса - рано утром при первом пуске .... да и другие станции в сети НИЧЕГО не создают - а все равно вылетает . И именно при изменении ЛОГИЧЕСКОГО поля ....

Виталий: А дрова у меня не DBFCDX а именно COMIX : _DBFCDX

saulius: Виталий, в ветке ELSE (где МЕТКА-2) невижу DBUNLOCK()

Виталий: Я просто порезал текст - там действительно небыло DBUNLOCK() . Я поставил - всё равно "ошибается" ! Блин - надоело мне заглушки выставлять на ERROR ! Стек жрёт !

SergeJa: а строить индекс по DTOC - неправильно. надо пользовать DTOS _Date_Format_ меняется - и кирдык. UNIQUE индексы также неприменимы (обсуждалось уж на форуме).

saulius: Виталий, Можно сделать кусок программы и локально получить стабильную ошибку ? Надо выяснить суть проблеммы. Какие заглушки ?

Виталий: Заглушки - это в смысле перехват ошибок на процедуру польщователя ... Кстати а что там про UNIQUE ??? Неприменимы в смысле когда ? Если вместе с логическим полем (составной индекс) или как ? По поводу построения DTOC-DTOS - у меня в программе формат ДАТЫ не меняется .... извините - 10 лет работает

SergeJa: PROC main FIELD qq dbCreate( "test1", {{'qq','C',10,0}}) use test1 aEval( Array(5),{|_1,_2| _1 := StrZero(_2,10), ; __dbAppend(), Field->qq := _1, ; __dbAppend(), Field->qq := _1 }) index on qq to test1 UNIQUE FOR !DELETED() dbGoTop() dbDelete() // удаляю запись 1 (qq == '0000000001') // замечу, что есть запись 2 (qq == '0000000001') dbEval({|| QOut(Field->qq) }) // где '0000000001' от 2-й записи? return

SergeJa: PROC main FIELD qq LOCAL i SET DELETED OFF dbCreate( "test1", {{'qq','C',10,0}}) use test1 aEval( Array(5),{|_1,_2| _1 := StrZero(_2,10), ; __dbAppend(), Field->qq := _1, ; __dbAppend(), Field->qq := _1 }) index on qq to test1 UNIQUE FOR !DELETED() index on qq to test2 UNIQUE ADDITIVE dbGoTop() dbDelete() // удаляю запись 1 (qq == '0000000001') // замечу, что есть запись 2 (qq == '0000000001') For i := 1 to 2 ? OrdSetFocus(i) dbEval({|| QOut(Field->qq), QQOut(STR(RecNo())+IIF(Deleted(),' Deleted','')) }) Next return

Виталий: SergeJa И что из твоего кода ? Когда делаю удаление - привычка SKIP(0) ....

SergeJa: Про SKIP(0) не понял. 10 лет программе? Мой тестик запусти. Sapienti sat.

Виталий: SKIP(0) - иногда чтоб рефрешик был записей ... Моя программулинка уже с 1995 года крутится .... начиналось с 5.0 и дошло до 5.3 . Думал уйти в винду ... да появился PageScript ... и пришлось остаться .... Про тестик расскажи поподробнее - а то не понял что где должно показать ?

SergeJa: рефреш бессмысленен в данном случае. для сборки теста сохранить мой примерчик в qqq.prg и ... clipper qqq.prg /m/n/a/w rtlink fi qqq ------- результат 0000000002 3 0000000003 5 0000000004 7 0000000005 9 0000000001 1 Deleted 0000000002 3 0000000003 5 0000000004 7 0000000005 9 ---- Диагноз уникальным индескам ставь сам. В анамнезе: после удаления записи данные индекса не соответствуют желаемым. Надеюсь, что твоя программа не обслуживает нужды стратегических объектов (живу я на северо-западе РФ :) ). Успехов!

Виталий: Тоесть нет смысла держать в индексе !DELETED() !

Виталий: Вот сегодня попробовал построить индексы без !DELETED() .... результат тот-же ! ошибка не ушла

SergeJa: Виталий пишет: Тоесть нет смысла держать в индексе !DELETED() ! Упс. Я - о другом. Более простой пример. PROC main FIELD qq SET DELETED ON dbCreate( "test1", {{'qq','C',1,0}}) USE test1 // добавляю две записи APPEND BLANK REPLACE qq WITH '1' APPEND BLANK REPLACE qq WITH '1' INDEX ON qq TO test2 UNIQUE GO TOP // тут видна одна запись. первая ? 'Цикл до удаления записи #1' WHILE .NOT. EOF() ? 'Запись',RECNO(),'из',LASTREC() SKIP ENDDO ? 'Удаление записи #1' GO TOP DELETE // запись #1 удалена GO TOP // а тут EOF. несмотря на наличие неудаленной записи #2 ее нет в индексе ? 'Цикл после удаления записи #1.' WHILE .NOT. EOF() ? 'Запись',RECNO(),'из',LASTREC() SKIP ENDDO ? 'Неудалённая запись #2 не видна, не так ли?' return // теперь рассмотрим твой индекс, например "все даты продаж (для быстрого меню ДАТЫ)" INDEX ON DATEP TAG DATEPU TO ("LANJROPT") FOR !DELETED() UNIQUE допустим, сегодня стряслись две продажи (#1 и #2). сообразно, в файле две записи с одинаковым значением в DATEP. В индекс с тегом "DATEPU" попадает продажа #1 (в моём примере это 'Цикл до удаления записи #1'). После ее удаления (уверен, что такое бывает в жизни) продажа #2 будет не видна ('Цикл после удаления записи #1.') и в "быстром меню ДАТЫ" будет чепуха. ошибка не ушла говорят, помогает: http://www.bubny.ru/

Виталий: Ха ! Дело в том что я чаще всего делаю так - значения УДАЛЯЕМЫХ полей обнуляю - тоесть коды товаров или клиентов =0 а даты REPLACE DATEP WITH CTOD("00/00/00") "это чтоб индексы правились . Ну и конечно DELETE . вот и все хитрости !

saulius: Это правильно, но програмка с ошибкой 8006 и базой было бы чудесно!

Виталий: в смысле - скинуть для теста ???

Виталий: Так тема ушла в никуда . Жаль .

suv2: Виталий пишет: Так тема ушла в никуда . Жаль . чем тебя не удовлетворили ответы?

Виталий: Так и не ушла проблема с ошибкой . Не понял в чем ошибка Неуже-ли из-за того что : при изменении значения записи - если именно эта запись была в другом ключе как UNIQUE - её уже не находит ? Тогда зачем везде описывается что "при изменении значения - обновляются значения индексов " Что теперь перекраивать без индексов UNIQUE ?????

suv2: тебе ответили - не используй стандартный DBFCDX - ОН ГЛЮЧНЫЙ

suv2: 2) ФАК - индексы UNIQUE должны строится для РАЗОВЫХ запросов. Сделал, чет-то там посчитал и выкинул. Эти индексы НЕЛЬЗЯ использовать, если база изменяется.

SergeJa: а зачем UNIQUE? собрать список уникальных ключей - просто LOCAL aKey := {}, cKey dbGoTop() DO While !EOF() cKey := sx_KeyData() // или &(IndexKey()) AADD( aKey, cKey ) ADDASCII(@cKey,1) DBSEEK(cKey,.T.) EndDO

Виталий: У меня CLIPPER 5.3 : SX_KEYDATA() Это SIX ?

Dima: Виталий пишет: SX_KEYDATA() Это SIX ? ДА

Виталий: И что мне с SIXом в 5.3 делать ?

Dima: Виталий пишет: И что мне с SIXом в 5.3 делать ? Ни чего. Есть аналогичный продукт , называется COMIX , он дружит с Clipper 5.3

Виталий: Так у меня от COMIX драйвер и есть ! _DBFCDX . !!!

SergeJa: Виталий пишет: И что мне с SIXом в 5.3 делать ? дык я специально написал: // или &(IndexKey())

alexmar: Эта связка без глюков? У себя обнаружил ошибку в Clipper 5.2e при штатном RDD DBFCDX неправильно строились индексы по ключу, задаваемому, как вычисляемое выражение числового типа. И выдавало в неготорых ситуациях внутреннюю ошибку: 1210 Data and Index files out of sync рассогласования базы и индекса С SIX 3 эти ошибки исчезли. Но может есть какие-то другие траблы?

suv2: alexmar пишет: 1210 Data and Index files out of sync рассогласования базы и индекса С SIX 3 эти ошибки исчезли. Но может есть какие-то другие траблы? мне жаль тебя огорчать, но в сиксе траблов до хрена и больше честно говоря, ни хрена он не работает

alexmar: suv2 пишет: мне жаль тебя огорчать, но в сиксе траблов до хрена и больше честно говоря, ни хрена он не работает Вот уже в течение месяца на разных машинах юзаю связку Clipper 5.2e + SIX3 (idx) + родной DBFNTX (ntx) и пока вроде с индексами проблем не возникало.

suv2: увидишь еще...

alexmar: Спасибо, утешил ... Вот сегодня с одной конторы кинули мне базу, которую я месяц назад конвертнул dbt -> fpt и пересадил под SIX3 (idx) Порядка десятка записей оказались запорченными. Произошло то же, что иногда раньше происходило и с dbt файлами. В разных записях указатели на номер блока (смещения) в memo файле оказываются одинаковыми. Обычно это происходило при сбоях питания. Буду надеяться, что причина в этом. Кто работал с fpt файлами, отзовитесь, насколько часто они имеют тенденцию ломаться?

alexmar: suv2 пишет: мне жаль тебя огорчать, но в сиксе траблов до хрена и больше честно говоря, ни хрена он не работает А что тогда делать?

suv2: ХЗ... Попробуй SIxNSX - более стабилен. Но тож таксе, на тройку с минусом. ( Мусор в базах - типичное явление. Ошибки в коде. В клиппер, в сикс, в эмуляции доса виндой...

suv2: suv2 пишет: А что тогда делать? ну еще адс попробуй))) если времени до хрена))) но это гиморрой еще тот))) там стока непробиваемых стен, что ой просто в лоб заменить дефолтный рдд на АДС не получится, придется долго пыхтеть. Опять же нетварь ставить, админы про нее как услышат - истово крестятся. АДС на IP не юзал, но там свой гиморрой есть, поспрошай Но АДС работает стабильно, быстро + переваривает большие базы, в отличие от остальных рдд

alexmar: suv2 пишет: ну еще адс попробуй Насколько я знаю, АДС не бесплатен. И потом, если бы это касалось только одной организации. У меня порядка 20 контор, где работают программы

alexmar: suv2 пишет: Попробуй SIxNSX Попробую SIxNSX и еще попробую низкоуровненые блокировки файлов, на время записи, как ты советовал. Если не поможет, буду отказываться от memo.

Григорьев Владимир: Есть старый добрый способ замены мемо полей обычным DBF файлом. Просто мемо запись "нарезается" на записи фиксированной длины. Эти фиксированные записи нумеруются и заносятся в обычный DBF файл. Ключом к записям этого файла служит составной ключ из первичного ключа основного DBF файла и порядковых номеров "нарезанных" мемо записей.

alexmar: Григорьев Владимир пишет: Просто мемо запись "нарезается" на записи фиксированной длины Спасибо, мне уже добые люди подсказали Вообще-то, когда-то давно, когда только встал вопрос о необходимости memo, я тоже думал их заменить таким образом. Но потом попробовал dbt, они показали себя достаточно надежными и я не стал заморачиваться с такими переделками. Но время шло, базы росли и в некоторых конторах начала возникать ошибка переполнения счетчика блоков. И я решил перейти на FPT. И похоже, поторопился, так как FPT начали ломаться...

suv2: alexmar пишет: Насколько я знаю, АДС не бесплатен. дык и клиппер не бесплатен) alexmar пишет: И я решил перейти на FPT. И похоже, поторопился, так как FPT начали ломаться... не драматизируй, люди работают на фпт и ничо, причем по 100 усеров ))) в основном не ломается) если у тебя ломается - может что с ОС не так или с сетью. Опять же - делай чисты protect mode, любая программа глючит при критически малой доступной памяти.



полная версия страницы