:: Visual Foxpro, Foxpro for DOS
оператор APPEND FROM
Ydin
Автор

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Про оператор APPEND FROM. Вот такой нюанс у этого оператора есть - если у курсора (или dbf), который FROM, есть удаленные записи, то они тоже подтягиваются. Наблюдал эффект от этого - в удаленных было поле со значением .NULL. Это приводило к ошибке типа "поле такое-то" не может принимать значение .Null. !Смотришь - а в курсоре все нормально, т.к. удаленных не видно! Ставишь set dele off - видно на brow! Эти удаленные записи тупо подтягиваются, но как удаленные и если не вступают в конфликт (типа .Null.) все пройдет. А если нет, можно потерять день, как я например.



Исправлено 1 раз(а). Последнее : Ydin, 08.10.21 19:45
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
И это во всех версиях такой "эффект"?
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Ydin
Автор

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Да
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
sphinx

Сообщений: 31179
Откуда: Каменск-Уральски
Дата регистрации: 22.11.2006
Нет хелпа под рукой. Там же можно условие задать, типа !DELETED().


------------------
"Veni, vidi, vici!"(с)
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
akvvohinc

Сообщений: 4216
Откуда: Москва
Дата регистрации: 11.11.2008
Такого нюанса нет.

Результат зависит от настройки SET DELETED в момент выполнения APPEND FROM:
1) если ON, то удаленные записи не "подтягиваются";
2) если OFF, то - "подтягиваются".

По крайней мере, в моей версии Фокса это так.
CLEAR
CLOSE ALL
CREATE TABLE table1 (field1 N)
INSERT INTO table1 VALUE (1)
INSERT INTO table1 VALUE (2)
DELETE
COPY STRUCTURE TO table2
USE table2 EXCLUSIVE
SET DELETED ON
APPEND FROM table1
? RECCOUNT() && 1
ZAP
SET DELETED OFF
APPEND FROM table1
? RECCOUNT() && 2
SET DELETED ON
APPEND FROM table1
? RECCOUNT() && 3
SET DELETED OFF
APPEND FROM table1
? RECCOUNT() && 5
Аналогично ведёт себя и команда COPY TO.



Исправлено 3 раз(а). Последнее : akvvohinc, 09.10.21 03:44
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Ydin
Автор

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
akvvohinc
Такого нюанса нет.
На простом примере, вроде, так!

А если так?
SET DELETED ON
CREATE CURSOR t2 (aa I null)
APPEND BLANK
REPLACE aa WITH .null.
dele
CREATE CURSOR t1 (aa I)
APPEND FROM DBF('t2')

поле aa не может принимать значение .Null.



Исправлено 2 раз(а). Последнее : Ydin, 09.10.21 16:42
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
akvvohinc

Сообщений: 4216
Откуда: Москва
Дата регистрации: 11.11.2008
Цитата:
поле aa не может принимать значение .Null.

Что в этом удивительного?
Вы же сами описали структуру t1 так, чтобы это поле не могло принять Null.
Добавьте Null к описанию поля, и вы увидите, что ни одна запись в t1 не попадет.

На возможный вопрос, а почему выдается эта ошибка, ведь запись с Null в выходной файл не должна попасть, я не отвечу, так как не знаю внутренностей (алгоритма работы) этой команды.

Главное видно - удаленная запись не перенесется и в этом случае.

Кстати, эта ошибка появляется даже в том случае, если вы отсекаете удаленные записи в условии самой команды:
APPEND FROM DBF('t2') FOR !DELETED()
Можно предположить, что сначала Фокс пытается преобразовать исходное значение к результирующему (и выдает ошибку, если не может это сделать), а лишь затем проверяет, а нужно ли переносить саму запись.



Исправлено 5 раз(а). Последнее : akvvohinc, 09.10.21 18:23
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Simple777

Сообщений: 33855
Дата регистрации: 05.11.2006
akvvohinc
Можно предположить, что сначала Фокс пытается преобразовать исходное значение к результирующему (и выдает ошибку, если не может это сделать), а лишь затем проверяет, а нужно ли переносить саму запись.

Видимо, так и есть.

Вообще некоторые команды имеют неочевидные нюансы (или баги?).

Например, команда APPEND FROM SDF DELIMITED WITH TAB имеет такой нюанс. Если реквизит, разделённый CHR(9),будет заключён в двойные кавычки (часто бывает, что названия юрлиц берутся в кавычки), то будет некорректная обработка. Этот случай уже как-то обсуждали здесь.

Вероятно, есть ещё команды, работающие при определённых условиях не так, как ожидается.



Исправлено 3 раз(а). Последнее : Simple777, 09.10.21 18:51
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
akvvohinc

Сообщений: 4216
Откуда: Москва
Дата регистрации: 11.11.2008
Кстати, только сейчас обратил внимание - в Help условие переноса, касающееся удаленных записей, описано:
Цитата:
If you are appending from a Visual FoxPro table, records in the table that are marked for deletion are appended if the current SET DELETED setting is OFF.

Ещё - выяснился один довольно интересный момент (во всяком случае, для меня), касающийся этой команды.
Кто-нибудь может, не запуская этот код, правильно назвать количество записей, попавших в t1?
CLEAR
CLOSE ALL
SET DELETED OFF
CREATE TABLE t2 (field1 I)
INSERT INTO t2 VALUES (1)
INSERT INTO t2 VALUES (2)
INSERT INTO t2 VALUES (3)
DELETE
CREATE TABLE t1 (field1 I)
APPEND FROM t2 FOR DELETED('t2')
? RECCOUNT()

Похоже, моё предположение о порядке выполнения команды APPEND FROM находит подтверждение.
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Deleted('t2') относится к текущей записи в курсоре t2 (сделай там GO TOP и увидишь разницу). Если хочешь чтобы он относился к импортируемым записям - убери алиас.
APPEND FROM t2 FOR DELETED()


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
akvvohinc

Сообщений: 4216
Откуда: Москва
Дата регистрации: 11.11.2008
Цитата:
Deleted('t2') относится к текущей записи в курсоре t2 (сделай там GO TOP и увидишь разницу).

Я-то уже в этом разобрался, раз предложил такой пример.

Хотя всё равно это выглядит довольно странно - как будто запись сначала безусловно импортируется, а потом начинается проверка, которая может привести к удалению этой записи, причем, физическому.
Ведь проверка проводится над текущей записью, которая только что "как бы импортирована".

И то, что написано по этому поводу в хелпе сначала кажется полной чушью:
Цитата:
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.
Я и сейчас считаю, что этот текст без дополнительных объяснений некорректен.
Попробуй объяснить, как надо понимать первое предложение абзаца (видимо, у меня совсем плохо с английским или с Фоксом).
Да и следующее предложение тоже не выглядит понятным.

Igor Korolyov
Если хочешь чтобы он относился к импортируемым записям - убери алиас.

Не хочу убирать.
Мы тут как раз и хотели понять, почему Фокс ругается на запись, которая не должна была попасть в выходную таблицу. Казалось бы он её вообще не должен был проверять.



Исправлено 9 раз(а). Последнее : akvvohinc, 10.10.21 13:15
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Каратаев

Сообщений: 3977
Откуда: Алматы
Дата регистрации: 04.12.2001
Можно добавить в команду проверку на NVL()
Ну что-то типа
APPEND FROM t2 FOR DELETED() and !empty(nvl(aa,""))
Писал на коленке, могу и ошибиться


------------------
Никогда не бывает настолько плохо, чтобы не могло быть еще хуже.
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Ydin
Автор

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Это не у меня было, я помогал искать проблему.
Там потом без меня ее решили легко.
Предлагал простое
Select * from t2 into curs t2
А потом Append From t2
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Igor Korolyov

Сообщений: 34580
Дата регистрации: 28.05.2002
Каратаев
Можно добавить в команду проверку на NVL()
Полагаю это не поможет...
Ydin
Предлагал простое
Select * from t2 into curs t2

Ну тут уж зависит от везения - что в выборку попадёт и будет ли оно нарушать структуру таблицы-приёмника. Для надёжности тут как раз и надо либо WHERE и "плохое" выкидывать, либо не * а явно поля перечислять и исправлять "нехорошие" - как раз таки NVL-ом для NULL-ов, ну для других типов - другие функции.
Это похоже на рекомендуемый для большинства "импортов" подход - сначала из источника затягиваем в таблицу наиболее гибкой/всё допускающей структуры, а потом уже проводим обработку и перегоняем (с проверками, конвертацией и т.п.) из этой staging таблицы/курсора в "основную".
Ну и да, если уж так делать, то стоит посмотреть в сторону конструкции INSERT ... SELECT ... а не APPEND FROM.


------------------
WBR, Igor
Ratings: 0 negative/0 positive
Re: оператор APPEND FROM
Ydin
Автор

Сообщений: 7648
Откуда: Киев
Дата регистрации: 16.12.2005
Игорь, там просто убрать удаленные. А дальше сами знают, что с NVL делать.
У меня есть ф-я в Фреймворке - она все поля Null исправляет в курсоре на пустые:
NotNull(tcCursor, tcFields)
tcFields можно не задавать, тогда все поля проверяет (исправляет)



Исправлено 2 раз(а). Последнее : Ydin, 15.10.21 15:06
Ratings: 0 negative/0 positive


Извините, только зарегистрированные пользователи могут оставлять сообщения в этом форуме.

On-line: 25 (Гостей: 25)

© 2000-2024 Fox Club 
Яндекс.Метрика