Форум » Clipper » Ошибка _DBFCDX/1020 для APPEND FROM » Ответить

Ошибка _DBFCDX/1020 для APPEND FROM

Andrey: /* Подскажите кто может. Как боротся с ошибкой: Error _DBFCDX/1020 Ошибка в типе данных Called from __DBTRANS(0) Called from __DBAPP(0) Called from MAIN(23) При копирование записей с одной базы в другую возникает эта ошибка. Я в структуру новой базы вставил с 58 поля 4 новых поля: NKODDOST;N;1;0 CKODDOST;C;25;0 SUMDVER;N;2;0 NKALITKA;N;1;0 И теперь при копирование записей возникает ошибка и на Clipper'e и на Harbour'e. Вообще-то это происходит всегда, когда добавляешь в DBFCDX-драйвер дополнительные поля в середине базы. Для решения этой проблемы приходиться запускать утилиту bdbfs.exe и ручками копировать с одной базы в другую. Достало это. Подскажите пожалуйста как решить эту проблему. Ниже привожу пример. */ FUNCTION MAIN() LOCAL aDbf #ifndef __HARBOUR__ #else REQUEST HB_CODEPAGE_RU866 hb_SetCodepage( "RU866" ) REQUEST HB_LANG_RU866 HB_LANGSELECT("RU866") #endif REQUEST DBFCDX RDDSETDEFAULT( "DBFCDX" ) USE ("dog_stru.dbf") ALIAS BASE_NEW EXCLUSIVE NEW aDbf := BASE_NEW->(DBSTRUCT()) CLOSE BASE_NEW DBCREATE("dog_new.dbf", aDbf) USE ("dog_new.dbf") ALIAS BASE_NEW NEW SELECT BASE_NEW SET DELETED OFF APPEND FROM ("dogovor.dbf") SELECT BASE_NEW ? LASTREC() wait RETURN NIL

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

Dima: Описание Команда APPEND FROM добавляет записи в текущий файл базы данных из текстового файла ASCII или другого файла базы данных. Добавляются только поля с одинаковыми именами и одного типа. Поля с одинаковыми именами как из текущего файла базы данных, так и из файла, имя которого определено аргументом <имя файла>, должны иметь одинаковый тип данных. Если это не так, то выполнение команды APPEND FROM завершится ошибкой "времени выполнения". При работе в сети для выполнения команды APPEND FROM не требуется, чтобы текущий файл базы данных был открыт для монопольного пользования. Не требуется и его блокировка с помощью функции FLOCK(). По мере добавления новой записи Clipper автоматически управляет доступом к ней. Когда вызывается команда APPEND FROM, Clipper делает попытку открыть файл с именем, указанным в аргументе <имя файла> с атрибутами "для совместного использования" и "доступ только для чтения". Если доступ невозможен, выполнение команды APPEND FROM завершается ошибкой "времени выполнения". Для получения дополнительной информации смотрите главу "Программирование в сетях" в книге " Программирование и утилиты ". ¦ Поля разной длины. Если поле в текущем файле базы данных является полем символьного типа и имеет длину больше, чем у входящих данных, Clipper дополняет его пробелами. Если текущее поле символьное и имеет длину поля меньше, чем у входящих данных, то данные из файла <имя файла> усекаются до длины принимающего поля. Если текущее поле числового типа и входящие данные не соответствуют его размеру, происходит ошибка времени выполнения.

Andrey: Да в том то и дело, что все поля одинакового типа, я их не трогаю. Беру и вставляю в середину базы еще несколько полей, которых небыло ! НОВЫЕ поля !!! И нечего документацию цитировать, это я знаю.... Вопрос стоит в том, что делать при появлении новых полей, можешь сам протестировать пример. Я его специально сделал, могу и базы выслать, дай мыло.

Dima: Andrey пишет: дай мыло. не дам , занят ;) APPEND FROM по жизни ни когда не использовал. Предпочитаю вместо вот таких команд использовать свои функции. В общем если глючит , сделай свою функцию и не парься ;)


ММК: Andrey пишет: И нечего документацию цитировать, это я знаю.... Мне кажется , что Дима все же прав :)))) SET HARDCOMMIT OFF MsgWait( "Конвертируем LIKAR.DBF ",,1 ) USE LIKAR NEW ALIAS Li SHARED cf = DbStruct() For i=1 to Len(cf) If cf[i,1]="QDADRJ" MsgWait( "Поле QDADRJ уже есть!",,1 ) W1:=.F. Endif If cf[i,1]="QDINDJ" MsgWait( "Поле QDINDJ уже есть!",,1 ) W2:=.F. Endif If cf[i,1]="QMTEL" MsgWait( "Поле QMTEL уже есть!",,1 ) W3:=.F. Endif Next If W1 AADD(cf,{'QDADRJ' ,'C',60,0}) Endif If W2 AADD(cf,{'QDINDJ' ,'N',6,0}) Endif If W3 AADD(cf,{'QMTEL' ,'C',11,0}) Endif Store .T. To W1,W2,W3 n:="nlik" DbCreate( n,cf) USE &n NEW ALIAS Tm APPEND FROM LIKAR USE MsgWait( "Конвертируем LIKARA.DBF ",,1 )

Pasha: Прогнал этот пример со своим файлом, вставил в середину новое поле, все нормально, никаких ошибок Проверь, ты не добавляешь в структуру поле, которое уже существует, с другим типом ? FUNCTION MAIN() LOCAL aDbf #ifndef __HARBOUR__ #else REQUEST HB_CODEPAGE_RU866 hb_SetCodepage( "RU866" ) REQUEST HB_LANG_RU866 HB_LANGSELECT("RU866") #endif REQUEST DBFCDX RDDSETDEFAULT( "DBFCDX" ) USE account ALIAS BASE_NEW EXCLUSIVE NEW aDbf := BASE_NEW->(DBSTRUCT()) AINS(aDbf, 4, {'CCC', 'C', 2, 0}, .t.) CLOSE BASE_NEW DBCREATE("dog_new.dbf", aDbf) USE ("dog_new.dbf") ALIAS BASE_NEW NEW SELECT BASE_NEW SET DELETED OFF APPEND FROM account.dbf SELECT BASE_NEW ? LASTREC() wait retu nil

ММК: Привет Паша ! :)) Дело в том , что примерчик то твой другой :)) Вот что у тебя - " Снял " структуру USE account ALIAS BASE_NEW EXCLUSIVE NEW aDbf := BASE_NEW->(DBSTRUCT()) Изменил AINS(aDbf, 4, {'CCC', 'C', 2, 0}, .t.) Ну и далее APPEND FROM account.dbf Другими словами , когда ты формируешь структуру из account.dbf и потом из этого же файла копируешь записи вероятность несоответствия полей не велика А Андрей структуру снимает с dog_stru.dbf, а копирует с dogovor.dbf. Что в примере я ему и написал. Вот здесь наверное и собака порылась...

Dima: ММК ты чего на мыло не отвечаешь , редиска ? ;)))))))

Andrey: Pasha пишет: AINS(aDbf, 4, {'CCC', 'C', 2, 0}, .t.) Паша, я об этом и пишу что при добавлении в середину базы нескольких полей происходит ГЛЮК ! А при вставки в конце базы глюков нет. Дима прав, согласен ! Буду писать свою функцию копирования записей. Только ана медленней будет.

Andrey: А куда ты "киданешь" ?

Dima: Andrey пишет: А куда ты "киданешь" ? Сюда скину , а пока чутка занят.

Dima: * Базы открываю сразу , но это при желании * можно переделать. Проверяется только имя поля * хотя можно проверять и тип и размерность * Клепал на скорую руку ;) Use aaaaa new Use bbbbb new Appfrm(aaaaa->(alias()),bbbbb->(alias())) ********* Func Appfrm(a,b) local i:=1 local sss:=b->(dbstruct()) local xy:=0 local old_rec:=0 do while !a->(eof()) for i=1 to a->(fcount()) xy:=ascan(sss,{|x| x[1]==a->(fieldname(i))}) if xy>0 if old_rec#a->(recno()) b->(dbappend()) old_rec:=a->(recno()) endif b->(fieldput(xy,a->(fieldget(i)))) endif next a->(dbskip()) enddo return nil

Петр: Andrey пишет: я об этом и пишу что при добавлении в середину базы нескольких полей происходит ГЛЮК ! А при вставки в конце базы глюков нет. Ни при добавлении в середину базы ( наверное вставке ), ни при вставке в конце базы ( добавлении ) никаких "глюков" не происходит. можно написать USE account ALIAS BASE_NEW EXCLUSIVE NEW aDbf := BASE_NEW->(DBSTRUCT()) AINS(aDbf, 2, {'CCC', 'C', 2, 0}, .t.) AINS(aDbf, 2, {'CCC', 'N', 2, 0}, .t.) AINS(aDbf, 2, {'CCC', 'L', 0, 0}, .t.) //( или что-нибудь в этом же духе). CLOSE BASE_NEW DBCREATE("dog_new.dbf", aDbf) и база создастся независимо от используемого RDD ( кстати этот "изврат" и использовать потом с пользой можна). Проблема возникает при APPEND FROM и Вам уже пытались обьяснить почему так происходит, и нечего шуметь по поводу полей, которых небыло ! НОВЫЕ поля !!! , новые так новые, для dog_new.dbf, а для dogovor.dbf ? И внимательно рассмотрите код Димы, тогда и вопрос с добавлением/вставкой для Вас прояснится .

Andrey: Петр пишет: Ни при добавлении в середину базы ( наверное вставке ), ни при вставке в конце базы ( добавлении ) никаких "глюков" не происходит. Ну может я пропустил что-то, но у меня это происходит периодически. Может проблема лежит и на поверхности, а может и глубже. Предлагаю тестировать на моих базах, где у меня ГЛЮЧИТ ! А то сделают несколько полей и у них все типа "работает" ! Код Димы смотрел, пока у меня неработает. Смотрю дальше. А воообще давайте пробуйте на моих базах, у меня полей штук под 200.

Лукашевский: Dima пишет: Проверяется только имя поля * хотя можно проверять и тип и размерность * Клепал на скорую руку ;) А я к уходу от стандартной append from шёл довольно долго... Но по крайней мере и тип проверяется, и работает довольно быстро. Вставить эту функцию в цикл надеюсь для Andrey (ну как не помочь тёзке! :-) не проблема. Function Append1From (from) local f_num, f_pos, f_get if PCOUNT() = 1 append blank endif for f_num=1 TO (from)->(FCOUNT()) f_pos = FIELDPOS( (from)->(FIELDNAME(f_num)) ) if f_pos > 0 f_get = (from)->(FIELDGET(f_num)) if VALTYPE(f_get) = TYPE(FIELDNAME(f_pos)) FIELDPUT(f_pos, f_get) endif endif next DBCOMMIT() return .T. Проблемы у меня были только если к принимающему файлу присобачены индексы с длинными результирующими выражениями ключа... но об этом я уже писал. Andrey - очень советую попробовать этот вариант, у меня уж каких только проблем не было - большинство решил :-)

Andrey: Короче говоря все намного проще. Cделал сравнение полей баз и всё прояснилось. Просто - как по документации: КОПИРУЕМЫЕ ПОЛЯ ДОЛЖНЫ БЫТЬ ОДНОГО ТИПА. __БД - dog_new.dbf_¦__БД dogovor.dbf__¦__ результат ───────────────+──────────────+──────────── NKODDOST....N (..1,0)¦_________________¦ нет поля CKODDOST...C (.25,0)¦_________________¦ нет поля SUMDVER......N (..2,0)¦_________________¦ нет поля NKALITKA......N (..1,0)¦_________________¦ нет поля PROC2007.....N (..6,2)¦_________________¦ нет поля END_BASE.....N (..1,0)¦END_BASE.....C (.1,0)¦ другой тип поля D_21_11_06..C (..1,0)¦_________________¦ нет поля И когда изменил это поле никак не вспомню.

Петр: Andrey пишет: А то сделают несколько полей и у них все типа "работает" ! Это к чему сказано? Andrey пишет: Просто - как по документации: КОПИРУЕМЫЕ ПОЛЯ ДОЛЖНЫ БЫТЬ ОДНОГО ТИПА. Andrey пишет: И нечего документацию цитировать, это я знаю.... Без комментариев. Лукашевский пишет: А я к уходу от стандартной append from шёл довольно долго... Ваша функция хуже стандартной append from.

Лукашевский: Петр пишет: Ваша функция хуже стандартной append from. A я и не претендую на особую оригинальность. Но, во-первых, она чётко работает, а во-вторых, там проверяется тип поля, что собственно и требовалось (так ведь оно и оказалось, что проблема была в типе поля!) - я в своё время столкнулся с той же самой проблемой, что и Andrey. И кстати, не будете ли Вы так любезны продемонстрировать Вашу функцию? Критиковать-то все горазды.

Andrey: Пришлось делать свою функцию копирования записей. Нет худа без добра, зато сделал "бегунок" копирования. Плюс, минс несколько секунд на Harbour'e юзер потерпит.

Dima: Andrey пишет: Нет худа без добра, зато сделал "бегунок" копирования. ну бегунок можно было и в команде append from использовать :) или в FOR его пихануть или в While ;) а код покажешь ? просто интерестно , может у кого то мысли появятся по оптимизации кода.

Andrey: Дима, я тебе несколько файлов могу скинуть на мыло, там еще несколько моих функций сидят. Сюда кинуть не могу, слишком много.



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