|
|
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Объясните, пожалуйста, поведение команды APPEND FROM в случае добавления записей по условию. В MSDN по этой команде написано: FOR lExpression Appends a new record for each record in the currently selected table for which lExpression evaluates to true (.T.). Records are appended until the end of the currently selected table is reached. If you omit FOR, the entire source file is appended to the currently selected table. Я хочу добавить только те записи, которые удовлетворяют условию. Для этого написал: Код: plaintext 1. 2. 3. 4. 5. 6. VFP6.0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 10:42:20 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
а если банально APPEND FROM DBF("kurs_step1") ; FOR BETWEEN(DATETIME(YEAR(cddate),; MONTH(cddate),DAY(cddate),; VAL(LEFT(cdtime,2)),VAL(SUBSTR(cdtime,4,2)),; VAL(RIGHT(cdtime,2))),dt_start,dt_end)=.T. ??? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 10:54:31 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
leafа если банально APPEND FROM DBF("kurs_step1") ; FOR BETWEEN(DATETIME(YEAR(cddate),; MONTH(cddate),DAY(cddate),; VAL(LEFT(cdtime,2)),VAL(SUBSTR(cdtime,4,2)),; VAL(RIGHT(cdtime,2))),dt_start,dt_end)=.T. ??? Тогда возникает ошибка Function argument value, type, or count invalid. В текущей выбранной таблице (получателе) поля cddate и cdtime пусты ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 11:28:19 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Там указатель не смещается! :-( APPEND FOR... вообще не очень хорош... А какой смысл в "BETWEEN(...)=.T."? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 12:25:42 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Формулировочка!... Короче - добавляются записи только, если в исходнике указатель стоит на записи из нужного диапазона, в противном случае нет? Еще я так понял - в обеих таблицах - по паре одинаковых полей - cddate (d) и cdtime (c,6). А кстати, зачем здесь использовать функцию DBF()? Нельзя - просто имя таблицы? (насчет BETWEEN()=.t. тоже тут верно заметили :) И вообще, мне кажется, вместо всей этой конструкции можно было бы написать и что-то попроще, типа: APPEND FROM kurs_step1 FOR BETWEEN(DTOS(kurs_step1.cddate)+kurs_step1.cdtime, dt_start, dt_end) Конечно - начальные и конечные значения диапазона надо будет персчитать тоже, как DTOS(date_start)+time_start и DTOS(date_end)+time_end. А так - APPEND FROM - вполне нормальное функция, зря ее здесь обидели :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 13:23:39 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Redrik А какой смысл в "BETWEEN(...)=.T."? Разве такое написание неверно? Равно .T. добавлено для удобочитаемости. Crispy А кстати, зачем здесь использовать функцию DBF()? Нельзя - просто имя таблицы? Не получится. Это курсор. В другом посте я об этом спрашивал. CrispyИ вообще, мне кажется, вместо всей этой конструкции можно было бы написать и что-то попроще, типа: APPEND FROM kurs_step1 FOR BETWEEN(DTOS(kurs_step1.cddate)+kurs_step1.cdtime, dt_start, dt_end) Попробовал, результат тот же. Код: plaintext 1. 2. 3. 4. 5. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 14:03:23 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Кузнецов ИгорьРазве такое написание неверно? Равно .T. добавлено для удобочитаемости. Верно... Дело вкуса! Не могу вспомнить свою проблему (давно было), но однажды я раз и навсегда отказался от сочетания APPEND'a и курсоров - здорово вляпался! Если позарез нужен APPEND, то подготавливаю нужный DBF, закрываю его и только потом делаю из него APPEND... И ERASE на закуску... ;-) Кузнецов ИгорьТогда возникает ошибка Function argument value, type, or count invalid. В текущей выбранной таблице (получателе) поля cddate и cdtime пусты Кстати, вот тут весьма странное место... Ведь FOR должен работать для источника , а он ругается на приемник ?! Хм... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 14:19:53 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
ну всё 1.вбирайте в свой курсор не кучу полей (DATETIME(YEAR(kurs_step1.cddate),; MONTH(kurs_step1.cddate),DAY(kurs_step1.cddate),; VAL(LEFT(kurs_step1.cdtime,2)),VAL(SUBSTR(kurs_step1.cdtime,4,2)) as Mytime ) а одно поле datetime !!! жизнь будет проще 2. проверте если в курсоре из которого идет подкачка null, т.к. Function argument value, type, or count invalid - есть сообщение о несовпадении типов когда вы указываете алиас явно Вы этим "фиксируете" запись в таблице подкачки , а если прогнать по всей таблице получиться несовпадение типов хотя может что и не так кода то не видно всего 2Redrik плохо что не помните подробностей хотелось бы послушать ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 14:32:05 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
вообще оказываеться Null не так страшен как кажеться просто подставиться системное значение а вот если например VAL(RIGHT(kurs_step1.cdtime,2))>59 то будет горе так что смотрите хотя вы же его из времени делаете? но алиас явно прописывать не стоит ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 14:48:40 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
leaf 2Redrik плохо что не помните подробностей хотелось бы послушать Скорее всего, он налетел на ситуацию, когда вместо курсора (т.е. временной таблицы) физически была просто переоткрыта таблица-источник и на нее наложили фильтр. =================================== Если SQL-запрос полностью оптимизируем, то вместо создания нового файла будет просто открыта та же самая таблица с наложенным на нее фильтром. Зачастую это очень неприятная неожиданность. Дело в том, что такую "отфильтрованную" таблицу нельзя использовать в качестве источника данных для последующих SQL-запросов, поскольку в этом случае непонятно, какие именно записи таблицы должны оказаться в результирующей выборке: с учетом "наложенного" фильтра или без. При попытке использования такой "отфильтрованной" таблицы в качестве источника данных для SQL-запроса Вы получите ошибку 1815 - "cursor" must be created with SELECT ... NTO TABLE Проверить, чем же физически является сформированный курсор, можно используя функцию DBF() SELECT * FROM MyTable INTO CURSOR TmpTable ?DBF('TmpTable') Если будет возвращено имя файла с расширением DBF, то данный курсор является той же самой исходной таблицей с наложенным на нее фильтром. Если Вы хотите при любых запросах быть уверенными, что курсор - это именно временная таблица, а не исходная таблица с наложенным фильтром, то Вам следует добавить опцию NOFILTER SELECT * FROM MyTable INTO CURSOR TmpTable NOFILTER Эта опция появилась только в 5 версии Visual FoxPro, хотя там она еще не была документирована. В более ранних версиях необходимо добавлять фиктивные условия или признаки группировки, чтобы исключить возможность оптимизации. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 14:49:32 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
leafкогда вы указываете алиас явно Вы этим "фиксируете" запись в таблице подкачки Повышенная смешливость вниманию мешает? RedrikТам указатель не смещается! P.S. Я не налетал на "переоткрывание"... какая-то другая ерунда творилась... Ну, сорри, не помню что именно ! :-( Разве что тогда у меня была "семерка" без SP... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:00:09 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
У меня впечатление такое, что условие FOR в команде APPEND FROM работает как семафор. По крайней мере в моем случае. Если условие выполнилось, то погнали добавлять записи, не выполнилось - добавлять нельзя. Не происходит проверки значений для каждой записи, только однократная проверка. Курсор kurs_step1 является курсором. Он был создан чуть ранее командой SELECT * FROM ... INTO CURSOR kurs_step1 и не пересоздавался. Никаких фильтров не накладывал. Переделал эту часть с использованием SCAN: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:21:00 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Можно через: INSERT INTO dbf_name [(fname1 [, fname2, ...])] SELECT [(fname1 [, fname2, ...])] FROM tablename WHERE condition ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:31:19 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
IgorProgrammerМожно через: INSERT INTO dbf_name [(fname1 [, fname2, ...])] SELECT [(fname1 [, fname2, ...])] FROM tablename WHERE condition А для VFP6 это подходит? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:34:35 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Нет... Начиная с 8 и более... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:36:39 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Кузнецов ИгорьЗдравствуйте. Объясните, пожалуйста, поведение команды APPEND FROM в случае добавления записей по условию. В MSDN по этой команде написано: FOR lExpression Appends a new record for each record in the currently selected table for which lExpression evaluates to true (.T.). Records are appended until the end of the currently selected table is reached. If you omit FOR, the entire source file is appended to the currently selected table. Я хочу добавить только те записи, которые удовлетворяют условию. Для этого написал:dt_start=<вычислено> dt_end=<вычислено> APPEND FROM DBF("kurs_step1") ; FOR BETWEEN(DATETIME(YEAR(kurs_step1.cddate),; MONTH(kurs_step1.cddate),DAY(kurs_step1.cddate),; VAL(LEFT(kurs_step1.cdtime,2)),VAL(SUBSTR(kurs_step1.cdtime,4,2)),; VAL(RIGHT(kurs_step1.cdtime,2))),dt_start,dt_end)=.T. Результат выполнения команды зависит от того, на какой записи будет стоять указатель записи в таблице kurs_step1. Если на записи, условие по которой дает .F., то добавления не будет. Если на записи, которая оценивается как .T., то добавляются все записи. Почему так? VFP6.0 Сорри не доглядел VFP6.0 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 15:39:25 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Курсор kurs_step1 является курсором. Он был создан чуть ранее командой SELECT * FROM ... INTO CURSOR kurs_step1 Честно говоря тогда все это и вообще очень даже странно! Разве можно ВООБЩЕ делать APPEND из курсора в DBF? Мне всегда Фокс говорил, что нет :). Если только это не критично, может тогда сделать ФАЙЛ DBF по имени kurs_step1? Или (если по-другим причинам нельзя) хотя бы - скопироваьт курсор сначала в DBF-ку. А насчет того, более короткого выражения, что я предлагал выше - это однозначно лучше - ведь чем больше всяких функций в фильтрах, индексах, SQL-выборках - тем медленнее все будет работать. Да и самому - путанницы больше. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 16:18:10 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
CrispyЧестно говоря тогда все это и вообще очень даже странно! Разве можно ВООБЩЕ делать APPEND из курсора в DBF? Мне всегда Фокс говорил, что нет :). А почему нет? Может это и не очень распостраненно, но принципиальных противопоказаний нет. В целом простая изначально затея обросла большим количеством трудностей. Что я хотел изготовить? Хотел организовать выборку из некоторого количества (заранее неизвестного) помесячных накоплений данных и отобразить в гриде. Выборка д.б. ограничена временными рамками, которые указал пользователь. Что я сделал? 1. сформировал список баз, которые мне понадобится просмотреть. обеспечил защиту от отсутствия какой-либо базы. 2. для каждой базы: открываю, делаю выборку по индексированным полям в курсор (kurs_step1), из него переношу в соответствии с уточняющими временными границами (индекса по этим полям нет) в итоговую таблицу (kurs_itog) 3. эту итоговую таблицу назначаю гриду и выполняю обрамление Можно конечно использовать только временные таблицы. Но не вижу большой разницы. Только файлы таблиц надо за собой с диска подчищать.. Да и хотелось не терять время на длительной выборке... P.S. Я тоже сторонник краткости написания, но вот увы.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 16:46:03 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Вообще-то, в команде APPEND FROM FOR-условие проверяет не то, что добавляется, а то, куда добавляется. Т.е. это самое FOR-условие контролирует текущую запись той таблицы в которую и идет вставка. Не совсем понимаю, что мешает сделать еще одну выборку? Т.е. сделай еще один Select-SQL по курсору с этим дополнительным условием, а потом закачай весь результирующий набор в таблицу. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 17:01:17 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
>Может это и не очень распостраненно, но принципиальных противопоказаний нет Принципиальных противопоказаний два - APPEND FROM требует наличия файла на диске что в случае курсора может и не наблюдатся. И еще APPEND FROM даже из таблицы, открытой в данный момент может давать глюки. Причем не всегда. Но пару раз напарывались ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 17:04:34 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
BurnИ еще APPEND FROM даже из таблицы, открытой в данный момент может давать глюки. Причем не всегда. Но пару раз напарывались 100% согласен! Тоже напарывался, и потому всегда закрываю перед APPEND'ом! ВладимирМВообще-то, в команде APPEND FROM FOR-условие проверяет не то, что добавляется, а то, куда добавляется. Т.е. это самое FOR-условие контролирует текущую запись той таблицы в которую и идет вставка. Владимир, скажите пожалуйста - моя мыслЯ похожа на правду? Получается, что "внутри" APPEND'a "спрятаны" 1. SCATTER из "источника" 2. проверка FOR 3. INSERT в "приемник", если FOR прошел И при этом нельзя использовать в FOR поля, которых нету в "приемнике", т.к. указатель записи в "источнике" не движется и, как следствие, получаем зависимость исключительно от текущей записи "источника". Да и вообще - "источник" может быть не открыт... Если ДА, то все-таки мне APPEND FOR как таковой не очень нравится... Получается, что при большом "источнике" там идет тупой перебор всех его записей - ведь в APPEND'e есть только FOR... Так что лучше подготовить DBF, а уж потом APPEND из него! Быстрее получится и с условиями по различающимся полям "приемник-источник" проблем никаких... IMHO ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 18:34:23 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
ВладимирМВообще-то, в команде APPEND FROM FOR-условие проверяет не то, что добавляется, а то, куда добавляется. Т.е. это самое FOR-условие контролирует текущую запись той таблицы в которую и идет вставка. ... Здравствуйте, Владимир! Позволю себе поправочку - проверяется то, что возможно проверить - потому что эта команда является универсальной и служит для добавления записей из файлов разных типов. 2 Игорь Кузнецов - поведение команды Append From в Вашем вопросе - вполне логичное - потому что мы имеем 4 вещи: 1) курсор (или таблица) куда идет идет добавление. 2) курсор kurs_step1 из которого нам хочется добавить записи 3) файл на диске dbf("kurs_step1") из которого реально эти записи добавляются. 4) заблуждение о том, что For-условие будет сканировать курсор. Ведь вы же сами явно указываете что проверять - значения полей cdtime и cddate курсора kurs_step1. Но загрузка идет не из этого курсора, а из его временного файла - поэтому сам курсор не сканируется, указатель записи остается на месте (как вы сами определили) и результат загрузки зависит только от текущих значений этого курсора. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 18:58:50 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Redrik BurnИ еще APPEND FROM даже из таблицы, открытой в данный момент может давать глюки. Причем не всегда. Но пару раз напарывались 100% согласен! Тоже напарывался, и потому всегда закрываю перед APPEND'ом! Да, это следует из того, что добавление идет из файла - а его содержимое на диске во время работы может не совпадать с данными в открытой таблице. Redrik Получается, что "внутри" APPEND'a "спрятаны" 1. SCATTER из "источника" 2. проверка FOR 3. INSERT в "приемник", если FOR прошел И при этом нельзя использовать в FOR поля, которых нету в "приемнике", т.к. указатель записи в "источнике" не движется и, как следствие, получаем зависимость исключительно от текущей записи "источника". Да и вообще - "источник" может быть не открыт... IMHO ;-) Указатель в источнике движется всегда, но обратиться к полям источника мы можем только если это файл таблицы (dbf). imho в других случаях For условие по источнику не применимо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 19:36:14 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Равиль! А давайте тогда сделаем НЕ курсоры. Более того, после создания таблиц закроем их и откроем вновь, чтоб не было вопросов типа "память-диск"! ;-) Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. Значит ли это, что указатель в "источнике" стоит на месте? получается, что ДА! А если сделать такую концовку: Код: plaintext 1. 2. 3. 4. Выходит, что алиас "источника" в FOR'е задавать просто нельзя! Проверяется, как сказал ВладимирМ, допустимость записи в "приемник" и т.д... Таки не люблю APPEND FOR... в тех случаях, когда низзя, а хоцца использовать условия по полям "источника", отсутствующим в "приемнике"... IMHO ;-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 14.06.2005, 21:03:16 |
|
||
|
Поведение APPEND FROM .. FOR
|
|||
|---|---|---|---|
|
#18+
Hi Redrik! Не знаю что там у тебя было, но я ни разу не встречался с ситуацией когда бы APPEND FROM (DBF("MyCursor")) не срабатывал, или давал ошибку. Независимо от размеров курсора и способа его создания. Правда я могу допустить что проблемы возникнут если этот же курсор в то-же самое время скажем в Grid светить (фоксу то надо обновлять экран и он таки "бегает" по этому курсору хотя для нас это и не заметно), или источником для комбо/листбокса сделать (тут меньше вероятность попасть, но кто его знает!), но вот так то я никогда и не делал - если нужно APPEND FROM - то только для того и делаем курсор... P.S. А вот FOR в этой команде я реально никогда и не использовал почему-то :) Posted via ActualForum NNTP Server 1.2 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.06.2005, 01:24:05 |
|
||
|
|

start [/forum/topic.php?fid=41&msg=33115766&tid=1594054]: |
0ms |
get settings: |
9ms |
get forum list: |
11ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
177ms |
get topic data: |
7ms |
get forum data: |
2ms |
get page messages: |
46ms |
get tp. blocked users: |
1ms |
| others: | 194ms |
| total: | 451ms |

| 0 / 0 |
