powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Детская задачка, помогите!!! Пожалуйста!!!
5 сообщений из 5, страница 1 из 1
Детская задачка, помогите!!! Пожалуйста!!!
    #34224867
Есть 2 таблицы, имеющие одинаковый формат.
Таблица 1 называется OLD.DBF и имеет поля: code1 (тип numeric, длина 10), name1 (тип char, длина 50). Таблица 2 называется NEW.DBF и имеет поля: code2 (тип numeric, длина 10), name2 (тип char, длина 50).
Задача: обновить и дополнить таблицу 1 записями из таблицы 2, т.е. если таблицы 1 и 2 содержат записи с одинаковыми значениями полей code1 и code2, то в результирующей таблице остаётся запись из таблицы 2; если в таблице 1 нет кода, который есть в таблице 2, то результирующая таблица должна содержать эту запись из таблицы 2.

Эти 2 таблицы имеют порядка 60 тысяч записей, кроме того ещё кучу полей. Размер каждой из них порядка 60 мегабайт.
Я решил, что надо разбить эту задачу.
Шаг1. Сначала выделил из поля code2 2й таблицы те коды, которые есть в 1й таблице:
SELECT new.code2 FROM new, old ;
INTO DBF ToDelete NOCONSOLE NOWAIT ;
WHERE old.code1=new.code2

Шаг2. Далее запускаю процедуру, которая должна отметить мне записи, подлежащие удалению:
SELECT ToDelete
GO TOP
FOR h=1 TO RECCOUNT()
SCATTER MEMVAR
DELETE FROM old WHERE old.code1=M.code2
SELECT ToDelete
SKIP
ENDFOR

Процедура выполняется ну ОЧЕНЬ ДОЛГО!(15 минут) И даже результат верный! Если бы программой пользовался только я, то можно жить, но... заказчику ТАКОЕ не понесёшь! Порекомендуйте, пожалуйста, как поступить. Как ускорить это действо? Необходимо учитывать, что
у заказчика комп довольно тормознутый(Windows 98 SE) и места на жёстком диске не более 1 Гигабайта...

Планируемый 3й шаг.

SELECT old
PACK
APPEND FROM new
...
Рейтинг: 0 / 0
Детская задачка, помогите!!! Пожалуйста!!!
    #34224992
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Примерно так:
индексируешь обе таблицы по ключу и пробуешь свой вариант :)
Код: plaintext
1.
2.
3.
4.
sele old
index on code1 tag code1
sele new
index on code2 tag code2
если надо еще быстрее, то можно сделать одновременный проход по двум таблицам
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
set order to code1 in old
set order to code2 in new
go top in old
go top in new
do while !eof('old') and !eof('new')
    do case
        case !eof('old') and new.code2 > old.code1
               delete in old
               skip in old
        case !eof('new') and (eof('old') or new.code2 > old.code1)
               append blank in old
               repl in old code1 with new.code2, name1 with new.name2
               skip in old && возврат на ту запись гда были
               skip in new
        case old.code1 = new.code2
               repl in old name1 with new.name2
               skip in new
               skip in old
    endcase
enddo
написал по памяти, возможно где-то в синтаксисе ошибся
...
Рейтинг: 0 / 0
Детская задачка, помогите!!! Пожалуйста!!!
    #34225002
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Забыл добавить
Если таблица открыта монопольно, то операции добавления/записи/удаления происходят заметно быстрее
...
Рейтинг: 0 / 0
Детская задачка, помогите!!! Пожалуйста!!!
    #34225042
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Перестарался delete in old не надо. Тебе же только добавить и обновить
...
Рейтинг: 0 / 0
Детская задачка, помогите!!! Пожалуйста!!!
    #34231992
fox_vik
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Михаил ТепловЕсть 2 таблицы, имеющие одинаковый формат.
Таблица 1 называется OLD.DBF и имеет поля: code1 (тип numeric, длина 10), name1 (тип char, длина 50). Таблица 2 называется NEW.DBF и имеет поля: code2 (тип numeric, длина 10), name2 (тип char, длина 50).
Задача: обновить и дополнить таблицу 1 записями из таблицы 2, т.е. если таблицы 1 и 2 содержат записи с одинаковыми значениями полей code1 и code2, то в результирующей таблице остаётся запись из таблицы 2; если в таблице 1 нет кода, который есть в таблице 2, то результирующая таблица должна содержать эту запись из таблицы 2.

Как уже говорилось, таблицы должны быть индексированы.

Этап 1 (обновление):
Код: plaintext
1.
UPDATE Old SET name1=New.name2, и т.д.;
 FROM new WHERE Old.code1=New.code2
Почитайте Help по UPDATE. Если в New встретится две записи с одинаковым code2, то обновится только первая из них.

Этап 2 (добавление):
Создать промежуточную таблицу с записями New отсутствующими в Old.
Код: plaintext
1.
2.
SELECT new.* FROM new;
  WHERE new.code1 Not IN (SELECT code2 FROM old);
  INTO TABLE TableAppend

Добавить эти записи в Old
Код: plaintext
1.
SELECT old
APPEND FROM TableAppend

Код не проверял, но идея, надеюсь, понятна.
Должно работать быстрее.

Из опыта: если таблицы индексированы по code1 и code2, то с не включенными set order to code1 и set order to code2 должно работать чуть быстрее, чем с включенными.

С Новым годом.
...
Рейтинг: 0 / 0
5 сообщений из 5, страница 1 из 1
Форумы / FoxPro, Visual FoxPro [игнор отключен] [закрыт для гостей] / Детская задачка, помогите!!! Пожалуйста!!!
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]