Автор | Сообщение |
|
| постоянный участник
|
Пост N: 104
Зарегистрирован: 12.09.06
|
|
Отправлено: 25.11.06 01:06. Заголовок: Ошибка _DBFCDX/1020 для APPEND FROM
/* Подскажите кто может. Как боротся с ошибкой: 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
[только новые]
|
|
|
| |
Пост N: 483
Зарегистрирован: 17.05.05
|
|
Отправлено: 25.11.06 13:00. Заголовок: Re:
цитата: | Описание Команда APPEND FROM добавляет записи в текущий файл базы данных из текстового файла ASCII или другого файла базы данных. Добавляются только поля с одинаковыми именами и одного типа. Поля с одинаковыми именами как из текущего файла базы данных, так и из файла, имя которого определено аргументом <имя файла>, должны иметь одинаковый тип данных. Если это не так, то выполнение команды APPEND FROM завершится ошибкой "времени выполнения". При работе в сети для выполнения команды APPEND FROM не требуется, чтобы текущий файл базы данных был открыт для монопольного пользования. Не требуется и его блокировка с помощью функции FLOCK(). По мере добавления новой записи Clipper автоматически управляет доступом к ней. Когда вызывается команда APPEND FROM, Clipper делает попытку открыть файл с именем, указанным в аргументе <имя файла> с атрибутами "для совместного использования" и "доступ только для чтения". Если доступ невозможен, выполнение команды APPEND FROM завершается ошибкой "времени выполнения". Для получения дополнительной информации смотрите главу "Программирование в сетях" в книге " Программирование и утилиты ". ¦ Поля разной длины. Если поле в текущем файле базы данных является полем символьного типа и имеет длину больше, чем у входящих данных, Clipper дополняет его пробелами. Если текущее поле символьное и имеет длину поля меньше, чем у входящих данных, то данные из файла <имя файла> усекаются до длины принимающего поля. Если текущее поле числового типа и входящие данные не соответствуют его размеру, происходит ошибка времени выполнения. |
|
|
|
|
|
| постоянный участник
|
Пост N: 105
Зарегистрирован: 12.09.06
|
|
Отправлено: 25.11.06 20:00. Заголовок: Re:
Да в том то и дело, что все поля одинакового типа, я их не трогаю. Беру и вставляю в середину базы еще несколько полей, которых небыло ! НОВЫЕ поля !!! И нечего документацию цитировать, это я знаю.... Вопрос стоит в том, что делать при появлении новых полей, можешь сам протестировать пример. Я его специально сделал, могу и базы выслать, дай мыло.
|
|
|
|
| |
Пост N: 484
Зарегистрирован: 17.05.05
|
|
Отправлено: 25.11.06 20:53. Заголовок: Re:
Andrey пишет: не дам , занят ;) APPEND FROM по жизни ни когда не использовал. Предпочитаю вместо вот таких команд использовать свои функции. В общем если глючит , сделай свою функцию и не парься ;)
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 26.11.06 09:54. Заголовок: Re:
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 )
|
|
|
|
| Администратор
|
Пост N: 407
Зарегистрирован: 23.05.05
|
|
Отправлено: 26.11.06 10:43. Заголовок: Re:
Прогнал этот пример со своим файлом, вставил в середину новое поле, все нормально, никаких ошибок Проверь, ты не добавляешь в структуру поле, которое уже существует, с другим типом ? 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
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 26.11.06 12:05. Заголовок: Re:
Привет Паша ! :)) Дело в том , что примерчик то твой другой :)) Вот что у тебя - " Снял " структуру 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. Что в примере я ему и написал. Вот здесь наверное и собака порылась...
|
|
|
|
| |
Пост N: 485
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.11.06 12:10. Заголовок: Re:
ММК ты чего на мыло не отвечаешь , редиска ? ;)))))))
|
|
|
|
| постоянный участник
|
Пост N: 106
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.11.06 14:10. Заголовок: Re:
Pasha пишет: цитата: | AINS(aDbf, 4, {'CCC', 'C', 2, 0}, .t.) |
| Паша, я об этом и пишу что при добавлении в середину базы нескольких полей происходит ГЛЮК ! А при вставки в конце базы глюков нет. Дима прав, согласен ! Буду писать свою функцию копирования записей. Только ана медленней будет.
|
|
|
|
| постоянный участник
|
Пост N: 107
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.11.06 18:00. Заголовок: Re:
А куда ты "киданешь" ?
|
|
|
|
| |
Пост N: 487
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.11.06 18:07. Заголовок: Re:
Andrey пишет: Сюда скину , а пока чутка занят.
|
|
|
|
| |
Пост N: 488
Зарегистрирован: 17.05.05
|
|
Отправлено: 26.11.06 18:48. Заголовок: Re:
* Базы открываю сразу , но это при желании * можно переделать. Проверяется только имя поля * хотя можно проверять и тип и размерность * Клепал на скорую руку ;) цитата: | 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 |
|
|
|
|
|
|
| постоянный участник
|
Пост N: 40
Зарегистрирован: 09.10.06
|
|
Отправлено: 26.11.06 20:54. Заголовок: Re:
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 ? И внимательно рассмотрите код Димы, тогда и вопрос с добавлением/вставкой для Вас прояснится .
|
|
|
|
| постоянный участник
|
Пост N: 110
Зарегистрирован: 12.09.06
|
|
Отправлено: 26.11.06 22:49. Заголовок: Re:
Петр пишет: цитата: | Ни при добавлении в середину базы ( наверное вставке ), ни при вставке в конце базы ( добавлении ) никаких "глюков" не происходит. |
| Ну может я пропустил что-то, но у меня это происходит периодически. Может проблема лежит и на поверхности, а может и глубже. Предлагаю тестировать на моих базах, где у меня ГЛЮЧИТ ! А то сделают несколько полей и у них все типа "работает" ! Код Димы смотрел, пока у меня неработает. Смотрю дальше. А воообще давайте пробуйте на моих базах, у меня полей штук под 200.
|
|
|
|
| |
Пост N: 52
Зарегистрирован: 08.04.06
|
|
Отправлено: 27.11.06 01:03. Заголовок: Аналог функции [Dima]
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 - очень советую попробовать этот вариант, у меня уж каких только проблем не было - большинство решил :-)
|
|
|
|
| постоянный участник
|
Пост N: 111
Зарегистрирован: 12.09.06
|
|
Отправлено: 27.11.06 09:36. Заголовок: Re:
Короче говоря все намного проще. 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)¦_________________¦ нет поля И когда изменил это поле никак не вспомню.
|
|
|
|
| постоянный участник
|
Пост N: 41
Зарегистрирован: 09.10.06
|
|
Отправлено: 27.11.06 13:31. Заголовок: Re:
Andrey пишет: цитата: | А то сделают несколько полей и у них все типа "работает" ! |
| Это к чему сказано? Andrey пишет: цитата: | Просто - как по документации: КОПИРУЕМЫЕ ПОЛЯ ДОЛЖНЫ БЫТЬ ОДНОГО ТИПА. |
| Andrey пишет: цитата: | И нечего документацию цитировать, это я знаю.... |
| Без комментариев. Лукашевский пишет: цитата: | А я к уходу от стандартной append from шёл довольно долго... |
| Ваша функция хуже стандартной append from.
|
|
|
|
| |
Пост N: 53
Зарегистрирован: 08.04.06
|
|
Отправлено: 28.11.06 02:57. Заголовок: Re:
Петр пишет: цитата: | Ваша функция хуже стандартной append from. |
| A я и не претендую на особую оригинальность. Но, во-первых, она чётко работает, а во-вторых, там проверяется тип поля, что собственно и требовалось (так ведь оно и оказалось, что проблема была в типе поля!) - я в своё время столкнулся с той же самой проблемой, что и Andrey. И кстати, не будете ли Вы так любезны продемонстрировать Вашу функцию? Критиковать-то все горазды.
|
|
|
|
| постоянный участник
|
Пост N: 114
Зарегистрирован: 12.09.06
|
|
Отправлено: 28.11.06 20:04. Заголовок: Re:
Пришлось делать свою функцию копирования записей. Нет худа без добра, зато сделал "бегунок" копирования. Плюс, минс несколько секунд на Harbour'e юзер потерпит.
|
|
|
|
| |
Пост N: 489
Зарегистрирован: 17.05.05
|
|
Отправлено: 28.11.06 20:19. Заголовок: Re:
Andrey пишет: цитата: | Нет худа без добра, зато сделал "бегунок" копирования. |
| ну бегунок можно было и в команде append from использовать :) или в FOR его пихануть или в While ;) а код покажешь ? просто интерестно , может у кого то мысли появятся по оптимизации кода.
|
|
|
|
| постоянный участник
|
Пост N: 115
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.11.06 00:12. Заголовок: Re:
Дима, я тебе несколько файлов могу скинуть на мыло, там еще несколько моих функций сидят. Сюда кинуть не могу, слишком много.
|
|
|
|
| постоянный участник
|
Пост N: 43
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.11.06 00:16. Заголовок: Re:
Лукашевский пишет: цитата: | И кстати, не будете ли Вы так любезны продемонстрировать Вашу функцию? |
| Не буду В подобных случаях использую или команду APPEND FROM или соответствующую ей встроенную функцию. Еще раз внимательно рассмотрите код который Вы предлагаете использовать вместо APPEND FROM 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. Да она работает, да она проверяет тип поля, а дальше что. А если VALTYPE(f_get) <> TYPE(FIELDNAME(f_pos)) тогда FIELDGET(f_pos) что даст? Наверное не всегда то, что ожидалось. Вы ведь просто теряете данные! Не случайно в документации по APPEND FROM указывается, что КОПИРУЕМЫЕ ПОЛЯ ДОЛЖНЫ БЫТЬ ОДНОГО ТИПА, а то будет вам ошибка времени исполнения, а другими словами смотри, что делаешь, не будет Clipper за тебя думать! Хотите анализируйте структуру таблицы приемника и таблицы источника (с помощью DBStruct) до вызова APPEND FROM, хотите пишите обработчик ошибок, хотите пишите свою функцию и там ловите ошибки, хотите ничего не делайте, надейтесь что все будет нормально. Ну и сама реализация - код Димы пошустрее будет.
|
|
|
|
|
| постоянный участник
|
Пост N: 116
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.11.06 00:59. Заголовок: Re:
Петр пишет: цитата: | Ну и сама реализация - код Димы пошустрее будет. |
| Петр ! Вы только отчасти правы. Здесь самое главное не быстродействие, а возможность сохранения записей из базы "приемника". И вы все расматриваете только одну ситуацию, а именно что база "приемник" целая, т.е. нет "битых" записей. Если они есть, то труба на всё. Т.е. нужно делать обработку и на прием "битых" записей. Я переодически с таким сталкиваюсь. И причину понять не могу.
|
|
|
|
| постоянный участник
|
Пост N: 45
Зарегистрирован: 09.10.06
|
|
Отправлено: 29.11.06 10:13. Заголовок: Re:
Andrey пишет: цитата: | Здесь самое главное не быстродействие, а возможность сохранения записей |
| 1) Одно другому не помеха 2) речь именно о сохранении, а не о сознательной потере данных Andrey пишет: цитата: | И вы все расматриваете только одну ситуацию |
| Я рассматривал не ситуацию, а конкретный код и его возможное поведение Andrey пишет: цитата: | а именно что база "приемник" целая, т.е. нет "битых" записей |
| Здесь не совсем понял Вашу мысль, но если в базе (приемнике, источнике - неважно) действительно есть "битые" записи - "то труба на всё" Если серьезно, то ситуация не из приятных. Но, думаю, Вы что-то напутали с терминологией. Andrey пишет: цитата: | Т.е. нужно делать обработку |
| Согласен, и реализация такой обработки может происходить по разному. Разработчики APPEND FROM предложили свой вариант - не самый худший. Ни ГЛЮКОМ, ни ошибкой здесь и не пахнет, стандартное задокументированое поведение.
|
|
|
|
| постоянный участник
|
Пост N: 118
Зарегистрирован: 12.09.06
|
|
Отправлено: 29.11.06 17:26. Заголовок: Re:
Dima Дима, я тебе несколько файлов могу скинуть на мыло, там еще несколько моих функций сидят. Сюда кинуть не могу, слишком много.
|
|
|
|
| |
Пост N: 490
Зарегистрирован: 17.05.05
|
|
Отправлено: 29.11.06 17:32. Заголовок: Re:
Andrey пишет: цитата: | Дима, я тебе несколько файлов могу скинуть на мыло |
| cмотри личное сообщение (ЛС)
|
|
|
|
| постоянный участник
|
Пост N: 122
Зарегистрирован: 12.09.06
|
|
Отправлено: 01.12.06 19:59. Заголовок: Re:
Так, а как быть если записи базы откуда копируем "битые" ? Т.е. записей МЕМО поля нехватает, записи с мусором и т.д.
|
|
|
|
| |
Пост N: 494
Зарегистрирован: 17.05.05
|
|
Отправлено: 01.12.06 20:25. Заголовок: Re:
Andrey пишет: цитата: | Т.е. записей МЕМО поля нехватает, записи с мусором и т.д. |
| была та же проблема и не раз , клиенты меня просто задергали. в общем в Clipper я отказался от использования memo полей.
|
|
|
|
| постоянный участник
|
Пост N: 123
Зарегистрирован: 12.09.06
|
|
Отправлено: 02.12.06 15:28. Заголовок: Re:
Хорошо, с мемо-полями понятно, что информацию не востановить, а как быть при копировании записей, если Clipper или Harbour ругается на ошибку чтения и просто сваливается программа ? Как написать обрабоку такой ситуации.
|
|
|
|
| постоянный участник
|
Пост N: 127
Зарегистрирован: 12.09.06
|
|
Отправлено: 04.12.06 11:11. Заголовок: Re:
Дима, а где ты хранишь данные типа МЕМО-полей. Для них же по барабану кто "рушит", Клипер или Харбор. Да вообще-то рушит скорее всего система, откуда-же идет мусор ?
|
|
|
|
| |
Пост N: 497
Зарегистрирован: 17.05.05
|
|
Отправлено: 04.12.06 15:08. Заголовок: Re:
Andrey пишет: цитата: | Дима, а где ты хранишь данные типа МЕМО-полей. |
| В символьных полях длиной от 100 до 250 символов , больше не нужно было.
|
|
|
|
| постоянный участник
|
Пост N: 52
Зарегистрирован: 09.10.06
|
|
Отправлено: 04.12.06 16:58. Заголовок: Re:
Andrey пишет: цитата: | Хорошо, с мемо-полями понятно, что информацию не восстановить |
| Попытаться можно. Например с помощью программы ASC (Advantage and SIx Commander) (автор Юрий Сухарев: suv - частый гость этого форума). Файл ->Доктор - совмещает проверку заголовка, memo, а также содержимого НЕ-memo полей (например, для поиска переполнения *** в числовых полях) (это из описания). Или вручную. цитата: | Да вообще-то рушит скорее всего система, откуда-же идет мусор ? |
| Этот вопрос в сети обсуждался довольно часто. Ищите. Устранить причину разрушения memo надо в первую очередь. Лично я храню MEMO или в dbt (проще структура, легче восстанавливать, размер при современных объемах ЖД значения не имеет), или в базе символьное поле - путь + имя файла (или просто имя файла), MEMO соответственно в указанном файле ( txt, rtf, doc, xls, jpg - в общем, что нужно). При втором подходе есть свои плюсы и минусы. Но все можно решить.
|
|
|
Ответов - 31
, стр:
1
2
All
[только новые]
|
|