Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Foxpro/Clipper/Dbase > Сравнение двух таблиц


Автор: Татка 6.6.2012, 15:24
Здравствуйте. Есть две таблицы: Spravochnik.dbf  и itog.dbf . Обе таблицы содержат реквизит номер цеха nz. Необходимо сравнить эти две таблицы по реквизиту "номер цеха" (nz) и в случае совпадения заменить реквизит код производства (kpr) массива Spravochnik.dbf  реквизитом код производства (kpr) массива itog.dbf.
Подскажите, пожалуйста, как это можно сделать?

Автор: Данкинг 6.6.2012, 15:30
Код

use Spravochnik in 1
use itog in 2
select 1
INDEX ON ALLTRIM(index) TO x1
SELECT 2
INDEX ON ALLTRIM(index) TO x2
SELECT 1
SET RELATION TO ALLTRIM(Spravochnik.index) INTO Itog ADDITIVE
REPLACE Spravochnik.kpr with itog.kpr for allt(Spravochnik.nz)==allt(itog.nz)

Автор: Reese 7.6.2012, 15:01
Relation давно уж надо на помойку выбросить
Код

local lc_nz, lc_kpr
use itog.dbf in 0 shared alias itog
use Spravochnik  in 0 shared alias Spravochnik 
select itog
scan
 lc_kpr = kpr
 lc_nz = nz 
 update Spravochnik  set kpr=lc_kpr where nz==lc_nz
 select itog
endscan


Можно update и по таблице сделать, но толь я не знаю как готовить, то ли он действительно такой медленный

Автор: Данкинг 7.6.2012, 15:10
Цитата(Reese @  7.6.2012,  16:01 Найти цитируемый пост)
Relation давно уж надо на помойку выбросить

Хм. А апдейтить Spravochnik столько раз, сколько строк в ITOG - это, конечно, лучше? smile

Добавлено через 4 минуты и 1 секунду
Да и зачем писать программу, если связь на уровне СУБД устанавливается, т.е. её средствами?

Автор: Reese 7.6.2012, 15:52
Цитата

Хм. А апдейтить Spravochnik столько раз, сколько строк в ITOG - это, конечно, лучше?

Сколько найдет. Если таких записей в Spravochnik  нет, то и апдейтиться ничего не будет.
Плюс моего решения - не зависит от индекса

Фокс до сих пор поддерживает @say, но это не значит что этим нужно пользоваться

Автор: Данкинг 7.6.2012, 20:17
Цитата(Reese @  7.6.2012,  16:52 Найти цитируемый пост)
Сколько найдет. 

Но каждый раз будет проходит все записи целиком. Смысл?

Автор: Reese 8.6.2012, 09:53
Цитата

Но каждый раз будет проходит все записи целиком. Смысл? 


Такой же как и в 

Цитата

SET RELATION TO ALLTRIM(Spravochnik.index) INTO Itog ADDITIVE
REPLACE Spravochnik.kpr with itog.kpr for allt(Spravochnik.nz)==allt(itog.nz)


В вашем случае тоже обрабатываются все записи.

Просто update понятнее т.к. такой код читать легче чем искать где и  как устанавливали relation, и безопаснее, т.к. в случае сломанного индекса ваш пример во всей таблице Spravochnik поставит в поле kpr одно значение, а в моем - просто отработает медленнее.

 

Автор: Данкинг 8.6.2012, 11:10
Цитата(Reese @  8.6.2012,  10:53 Найти цитируемый пост)
В вашем случае тоже обрабатываются все записи.

Не знаю именно самого механизма работы - может быть, там используется какой-то свой внутренний UPDATE. Я про то, что при связывании я делаю всё одной командой - REPLACE - и жду, пока она отработает. Да и в любом случае - зачем писать программу, если можно сделать одной строкой?

Добавлено через 43 секунды
Цитата(Reese @  8.6.2012,  10:53 Найти цитируемый пост)
в случае сломанного индекса 

Какого сломанного: я в подобных случаях обычно заново переиндексирую.

Автор: Reese 8.6.2012, 13:07
Цитата

Да и в любом случае - зачем писать программу, если можно сделать одной строкой?

Какой же одной ? В одну строчку разница.

Цитата

Какого сломанного: я в подобных случаях обычно заново переиндексирую. 


А если индекс сломался во время работы replace for ?

Автор: Данкинг 8.6.2012, 13:20
Цитата(Reese @  8.6.2012,  14:07 Найти цитируемый пост)
Какой же одной ? В одну строчку разница.

Нет, это просто я написал, как это сделать программно. Но самом фоксе же есть построитель выражений, в том числе и для установки связей. Я всегда его и использую.
Цитата(Reese @  8.6.2012,  14:07 Найти цитируемый пост)
А если индекс сломался во время работы replace for ?

Это с чего вдруг? Вот ни разу подобного не было.

Автор: Reese 8.6.2012, 14:56
Цитата

Но самом фоксе же есть построитель выражений

1. Этот построитель дал вам тот-же код
2. Использование визардов - зло


Цитата

Это с чего вдруг? Вот ни разу подобного не было.

При сетевой работе (особенно если программа написана через всякие relation) - слетают регулярно. (Особенно если некоторые пользователи вместо кнопки отмена выдергивают вилку компа)

Автор: Данкинг 8.6.2012, 17:29
Цитата(Reese @  8.6.2012,  15:56 Найти цитируемый пост)
 Этот построитель дал вам тот-же код

Правильно, но я же PRG не писал.
Цитата(Reese @  8.6.2012,  15:56 Найти цитируемый пост)
 Использование визардов - зло

Как правило - да, но не всегда и не везде.
Цитата(Reese @  8.6.2012,  15:56 Найти цитируемый пост)
 (Особенно если некоторые пользователи вместо кнопки отмена выдергивают вилку компа)

При чём здесь это? А что будет, если прилетят зелёные человечки и унесут системник?

Автор: Reese 9.6.2012, 09:24
Про выдергивание вилки я конечно несколько утрировал, но я часто встречался с тем что пользователи сбрасывают задачу или жмут reset когда уже нажали "сохранить" и вспомнили что-что-то забыли.

Автор: Данкинг 9.6.2012, 11:33
Цитата(Reese @  9.6.2012,  10:24 Найти цитируемый пост)
сбрасывают задачу или жмут reset когда уже нажали "сохранить" и вспомнили что-что-то забыли. 

Да при этом вообще таблица не сохранится, что бы с ней ни делали. Именно RELATION или индексы тут ни при чём.

Автор: Reese 9.6.2012, 13:01
Цитата

Да при этом вообще таблица не сохранится

Причем тут сохранение таблицы?
Таблица уже есть. В нее записывают данные при помощи уже написанной программы, а написан процесс сохранения какого нибудь документа при помощи relation, append blank, и replace.
База лежит на сетевом диске, работают два пользователя, и один из них сбрасывает задачу в момент записи данных. Вот тут обычно и происходит слом индексов. (обычно при попытке искать по такому индексу всегда возвращается первая запись). 

Автор: Данкинг 9.6.2012, 14:10
Цитата(Reese @  9.6.2012,  14:01 Найти цитируемый пост)
Причем тут сохранение таблицы?

В смысле, если открыть таблицу, записать что-нибудь в поле и снять задачу VFP, то записанные данные не сохранятся. 
Цитата(Reese @  9.6.2012,  14:01 Найти цитируемый пост)
База лежит на сетевом диске, работают два пользователя

В сетевом режиме на фоксе лучше уже вообще не работать, он всё же не для этого.

Автор: Reese 9.6.2012, 14:34
Цитата

В смысле, если открыть таблицу, записать что-нибудь в поле и снять задачу VFP, то записанные данные не сохранятся. 

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


Цитата

В сетевом режиме на фоксе лучше уже вообще не работать, он всё же не для этого.

Он именно для этого и разрабатывался.

Автор: Данкинг 9.6.2012, 16:34
Цитата(Reese @  9.6.2012,  15:34 Найти цитируемый пост)
В этом случае сохранение происходит только после ухода с поля. 

Нет. Сохранение происходит или при закрытии (нормальном) фокса, или же принудительно командой FLUSH.
Цитата(Reese @  9.6.2012,  15:34 Найти цитируемый пост)
Он именно для этого и разрабатывался.

Может быть, когда альтернативы не было. Но сейчас я не представляю сетевую работу с фоксовой таблицей в 13 миллионов записей (какая вот у меня есть на FireBird).

Автор: Reese 9.6.2012, 17:47
Цитата

Нет. Сохранение происходит или при закрытии (нормальном) фокса, или же принудительно командой FLUSH.

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

Цитата

Может быть, когда альтернативы не было. Но сейчас я не представляю сетевую работу с фоксовой таблицей в 13 миллионов записей (какая вот у меня есть на FireBird). 


Он и сейчас занимает свою нишу. Но сепецов по нему все меньше и меньше, да и Microsoft не хочет его развивать. Не выгоден он им. 

Да. 13 миллионов будет уже тяжеловато для фокса. Но на 10-20 рабочих мест при размере таблиц в пределах 10 миллионов с сумарным весом БД  в пределах 2 гб - фокс чуствует себя совсем не плохо. Опять же вместо сервера можно поставить простенький NAS (главное чтоб SMB нормально поддерживал и блокировки работали) и в случае какой нибудь поломки можно и по телефону объяснить что и куда скопировать т.к. уж чего-чего а с файлами всякие тетушки обычно справляются. Если что-то крупнее, то я тоже предпочту FireBird или DB2 (благо бесплатная версия не имеет ограничений на размер БД) к ним можно из того же Фокса подключиться.

Автор: Данкинг 9.6.2012, 19:15
Цитата(Reese @  9.6.2012,  18:47 Найти цитируемый пост)
Если быть точным, то сохранение происходит в зависимости от типа буферизации. 

А где она меняется?
Цитата(Reese @  9.6.2012,  18:47 Найти цитируемый пост)
 Но это что касается работы с таблицей вручную, а так с таблицами все таки не работают. 

Работают-работают. smile 
Цитата(Reese @  9.6.2012,  18:47 Найти цитируемый пост)
10 миллионов с сумарным весом БД  в пределах 2 гб 

Это если там одно поле только. Ну или два.

Автор: Reese 9.6.2012, 22:01
Цитата

А где она меняется?

свойство BufferMode у объектов _screen и form

Цитата

Это если там одно поле только. Ну или два.

15 полей. объем таблицы - чуть меньше 1 Гб

Цитата

Работают-работают.

А смысл. Для такой работы обычно табличные процессоры используют.

Автор: Данкинг 9.6.2012, 22:13
Цитата(Reese @  9.6.2012,  23:01 Найти цитируемый пост)
свойство BufferMode у объектов _screen и form

А в меню фокса нет такой опции?
Цитата(Reese @  9.6.2012,  23:01 Найти цитируемый пост)
15 полей. объем таблицы - чуть меньше 1 Гб

Ну, значит, поля по размеру небольшие.
Цитата(Reese @  9.6.2012,  23:01 Найти цитируемый пост)
А смысл. Для такой работы обычно табличные процессоры используют. 

Какие ещё процессоры: открыл таблицу в фоксе - и вперёд.

Кстати, попробовал связку и UPDATE - связка в разы быстрее работает, как я и говорил.

Автор: Reese 10.6.2012, 11:06
Цитата

Ну, значит, поля по размеру небольшие.

В в среднем C(50)

Цитата

А в меню фокса нет такой опции?

Нет. А зачем она там ?

Цитата

Какие ещё процессоры


Excel, Calc и т.д.

Цитата

стати, попробовал связку и UPDATE - связка в разы быстрее работает, как я и говорил.

А поля, по которым идет поиск,  проиндексировали ? Ну не может оно в разы быть медленнее

Автор: Данкинг 10.6.2012, 11:28
Цитата(Reese @  10.6.2012,  12:06 Найти цитируемый пост)
Excel, Calc и т.д.

Только просматривать и редактировать таблицу в фоксе куда удобнее, чем в Excel, который к тому же только 65 с чем-то там тысяч записей поддерживает. В Calc с версии ОО 3.3 поддерживается и больше, но при этом файл на 300000 записей открывается час, т.е. скорость у ОО оставляет желать лучшего.
Цитата(Reese @  10.6.2012,  12:06 Найти цитируемый пост)
А поля, по которым идет поиск,  проиндексировали ?

А, забыл. smile Прога на работе, тогда после выходных гляну.
Цитата(Reese @  10.6.2012,  12:06 Найти цитируемый пост)
В в среднем C(50)

Ну вот, смотря что хранить в такой таблице.

Автор: Данкинг 17.6.2012, 21:21
Цитата(Данкинг @  10.6.2012,  12:28 Найти цитируемый пост)
Прога на работе, тогда после выходных гляну.

Глянул, кстати. UPDATE с индексированным полем аналогично долго работает.

Автор: Reese 18.6.2012, 09:56
Цитата

 UPDATE с индексированным полем аналогично долго работает. 

Ну быть такого не может.
Можете скинуть код с описанием полей и индексов? 

Автор: Данкинг 18.6.2012, 10:21
Ну, суть в том, что вторая таблица индексируется по полю (пусть будет INDEXPOLE), далее идёт цикл по первой таблице и запрос типа такого:
Код

index table2 on left(INDEXPOLE,100) to xxx
update table2 set table2.Pole1=table1.Pole1, table2.Pole2=table1.Pole2, table2.Pole3=table1.Pole3 where allt(table1.INDEXPOLE)==allt(table2.INDEXPOLE)

Автор: Reese 18.6.2012, 11:38
так я же писал что update по таблице действительно медленный
SCAN + update - тогда быстро
И еще, какой уровень оптимизации? Что-то я не уверен что в вашем случае UPDATE  будет использовать индекс.

Автор: Данкинг 18.6.2012, 13:24
А при чём здесь scan ? Какая разница, откуда я получаю значение?

Автор: Reese 18.6.2012, 15:05
При том что join на update-е у фокса медленный. Поэтому Join эмулируем через select ... into cursor и scan c update-ом.
Увы, но это то ли просто особенность фоксового SQL-движка, то ли, вообще, баг.

Автор: klepus 14.10.2012, 14:31
Привет, у меня похожий вопрос, но у меня не получается... 
Есть 2 таблицы (табл1, табл2).
Таблица 1 - это курсор в котором всего 2 столбца.
Таблица 2 - это 2 этих же столбца + ещё 2 других.
Одинаковые столбцы z2 C(8), z3 N(8)
Мне надо, чтобы при удаление/добавление/редактирование, записей в этих столбцах первой таблицы, тоже самое происходило во второй (Обратное не надо). Но остальные столбцы второй таблицы должны остаться без изменения. Если всё совпадает, то ничего не делать.
Вообщем, что бы таблица 2 реагировала на изменение в таблице 1 в общих столбцах, но она не должна терять информацию, которая содержится в других столбцах.

Автор: Данкинг 14.10.2012, 14:38
Цитата(klepus @  14.10.2012,  15:31 Найти цитируемый пост)
Мне надо, чтобы при удаление/добавление/редактирование

Это каким образом осуществляется?

Автор: klepus 14.10.2012, 14:44
Цитата(Данкинг @ 14.10.2012,  14:38)
Цитата(klepus @  14.10.2012,  15:31 Найти цитируемый пост)
Мне надо, чтобы при удаление/добавление/редактирование

Это каким образом осуществляется?

Ну первая таблица, редактируется кем то периодически, не зависимо от меня. То удалят строку, то добавят новую.
А моя (вторая таблица) должна всё это отражать в себе.

Автор: Данкинг 14.10.2012, 17:27
Цитата(klepus @  14.10.2012,  15:44 Найти цитируемый пост)
То удалят строку, то добавят новую.

Удаление осуществляется программно или вручную?

Автор: klepus 14.10.2012, 18:12
Цитата(Данкинг @ 14.10.2012,  17:27)
Цитата(klepus @  14.10.2012,  15:44 Найти цитируемый пост)
То удалят строку, то добавят новую.

Удаление осуществляется программно или вручную?

Вручную.

Автор: Данкинг 14.10.2012, 20:56
Тогда никак: триггеров на фоксе ещё не придумали.

Автор: Reese 18.10.2012, 11:43
Можно просто по таймеру проверять изменения.
Если таблица лежит в контейнере, то можно и триггер (вообще то они в фоксе есть).

Автор: Данкинг 18.10.2012, 12:08
Цитата(Reese @  18.10.2012,  12:43 Найти цитируемый пост)
то можно и триггер (вообще то они в фоксе есть). 

Где они есть: небось только в 9-м фоксе и только для таблиц в составе БД?

Автор: Reese 19.10.2012, 10:59
В 6-ом точно были. Но как я уже говорил, только для таблиц в контейнере БД.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)