ИЗ dbf в tps...

Clarion, Clarion 7

Модератор: Дед Пахом

Правила форума
При написании вопроса или обсуждении проблемы, не забывайте указывать версию Clarion который Вы используете.
А так же пользуйтесь спец. тегами при вставке исходников!!!
Ответить
Гость

Сообщение Гость »

Здравствуйте (Hello) clalist,

c6ee tps w2k
конвертю из dbf в tps (300 тыс.записей)
ждал 2 3 4 часа - бесполезно cpu занят при этом чуть-чуть
HDD горит лапочка - постоянно
Делал по 1000 записей затем снова stream и т .д. не помогло
где я ошибаюсь ?

Код: Выделить всё

  ! pens - tps
  ! re_pens - dbf
  
 Access:pens.open
 Access:re_pens.open
 Access:pens.UseFile()
 Access:re_pens.UseFile()
    Logout(1,pens)
    Lock(re_pens)
    Stream(re_pens)
    set(re_pens)
    loop
    next(re_pens)
    if errorcode() then break .
     pe:record :=: RE:record
     add(pens)
    end
    Flush(re_pens)
     Unlock(re_pens)
     Commit()
    END
     message('!!!!!!!!!!!!!')
  Access:pens.close
 Access:re_pens.close  
--
С уважением,
Талгат mailto:talgat@omsknet.ru
(г.Омск)

(Добавление)

Здравствуйте Талгат!

Каждые 1000 записей делай commit или переоткрывай файл!
В доке же написано это про ТПС.

--
С уважением, SAN mailto:vgsan@yandex.ru

Код: Выделить всё

Logout(1,pens)
Если даёшь Logout, то обязательно через какое-то число записей Commit, иначе происходит переполнение буфера ...

Код: Выделить всё

    Lock(re_pens)
     Stream(re_pens)
     set(re_pens)

Код: Выделить всё

RecNo#=0

Код: Выделить всё

     loop
     next(re_pens)
     if errorcode() then break .
      pe:record :=: RE:record
      add(pens)

Код: Выделить всё

                RecNO#+=1 
                If (RecNo# % 1000)=0 
                   Commit
                   Logout(1,Pens) 
            End 
---------------------------------------
C уважением,
Юрий Философов,
Главный программист
Корпорация "Диполь", Саратов
E-mail yufil@tacis-dipol.ru (служ)
yufil@mail.ru (дом)
ICQ#75924439


(Добавление)

Stream и Flash применяются к тому файлу, в который пишешь, т.е. в данном случае - файл pens. Перед началом цикла - объявить и обнулить счетчик, например: rc long(0). Внутри цикла после добавления записи в файл увеличить счетчик на 1 и проверить содержимое на 1000. Если условие выполняется ( добавлено 1000 записей), то выполнить слив буфера в файл:
Flush(pens)
Stream(pens)
и далее - в начало цикла.
В этом случае можно обойтись без транзакций, т.е.
не нужны операторы Logout - Commit. Можно наоборот - как и рекомендуют наши гуру - не применять Stream - Flush, а применять Logout - Commit на каждую 1000 записей.

С уважением,
Александр Полонский
Flush(pens)
Stream(pens)
и далее - в начало цикла.
Для больших файлов и ключей этого мтбыть мало!!!

--
С уважением, SAN mailto:vgsan@yandex.ru

(Добавление)

Вместо ADD поставь команду APPEND а в конце перестой ключи. У меня перезапись 2 500 000 записей идет 7 часов

С уважением
Виктор
vlenkov@mail.ru

Спасибо.
А где в конце - перестроить ?

--
С уважением,
Талгат

После перезаписи К тому-же для простой перезаписи совсем никчему включать
обработку транзакций

Код: Выделить всё

  Access:pens.open
  Access:re_pens.open
  Access:pens.UseFile()
  Access:re_pens.UseFile()
     set(re_pens)
     loop
     next(re_pens)
     if errorcode() then break .
      pe:record :=: RE:record
      append(pens)
     end
      message('!!!!!!!!!!!!!')
   Access:pens.close
  Access:re_pens.close
C уважением
Виктор

(Добавление)

Кстати самый простой вариант сделать конверсионную программу в словаре Клара сделает ее быстро и грамотно и работать будет со скоростью конвертации файла

С уважением
Виктор

Где как...если не сложно.

Талгат Хайсаров

В словаре в меню Файл CREATE CONVERSION PPROGRAM FOR ONE TABLE

С уважением
Виктор

Спасибо.
А ежели структыры таблиц разные, то уже не подойдет этот вариант

--
С уважением,
Талгат

Если структуры разные, откорректируй техт ручками , там где идет присвоение переменных

С уважением
Виктор
Написал: ClaList(2)
Гость

Сообщение Гость »

Код: Выделить всё

     Logout(1,pens)
Хорошо бы тут ошибочки проверить.
Если даёшь Logout, то обязательно через какое-то число записей Commit, иначе происходит переполнение буфера ...
Для простого пакетного добавления имхо лучше STREAM. Не будет ничего лишнего держать в памяти и при переполнении буффера просто сам автоматом выльет лишнее на диск.

Код: Выделить всё

     Lock(re_pens)
     Stream(re_pens)
Для входного файла Stream бесполезен. Если хочешь ускорить чтение, то поиграй размером буфера. Но боюсь, дело в том, что dbf-овские драйверы не поддерживают "сырое" чтение - SEND(file, 'QUICKSCAN = on') и за каждой записью лезут на диск. Тогда только через DOS и ручной разбор структуры файла.

Код: Выделить всё

     set(re_pens)
         RecNo#=0
     loop
     next(re_pens)
     if errorcode() then break .
Ну почему, если начинаем и заканчиваем в АВС, то в промежутке действуем
самостоятельно?.

LOOP UNTIL Access:re_pens.next()

Код: Выделить всё

      pe:record :=: RE:record
      add(pens)
If NOT Access:pens.TryInsert() then Do CheckError . ! А вообще-то, хотели APPEND(pens)

Код: Выделить всё

                 RecNO#+=1
                 If (RecNo# % 1000)=0
                    Commit
                    Logout(1,Pens)
          End
     end
     Flush(re_pens)
      Unlock(re_pens)
      Commit()
Вот тут Build(pens), если добавляли append-ом.
END
Не много ли ендов?

WBR, Nick Tsigouro. MailTo:Nick@arsis.ru


(Добавление)

Logout - Commit рекомендуется для мультидоступа. Т.е. когда параллельно с добавлением работают еще люди, и их нельзя замораживать. С Logout - Commit проще избежать дедлоков. При мультидоступе, о скоростях можно забыть, и прерывать транзакцию нужно прежде всего, чтобы дать поработать другим.
Поэтому между Commit и новым Logout нужно делать паузу (запускать следующий logout по таймеру - т.е. действовать в духе PROCESS/REPORT). С точки зрения буфферизации при add-e прерывание транзакции спасает не сильно, а может и навредить, потому что при commit-e все будет выливаться на диск, а при последующих add-ах блоки с ключами практически полностью опять будут подгружаться в память.

ЗЫ. Все, ес-но, касается исключительно tps.

WBR, Nick Tsigouro
Написал: ClaList(2)
Гость

Сообщение Гость »

Я так понял, что речь шла об однопользовательском десктопном приложении. Лично я в этом случае использую только Stream - Flush.
Но, помнится, в рассылке кто-то из гуру советовал и для такого случая использовать транзакции для ускорения пакетной записи в файл.

С уважением,
Александр Полонский
Написал: ClaList(2)
Гость

Сообщение Гость »

Проще всего:

Open(имя source-файла)
Open(имя target-файла)
Set(имя source-файла)
Stream(имя source-файла)
Loop
Next(Имя source-файла)
<проверили на ошибочки и на конец (файла!)>
ВЫПОЛНИЛИ ПЕРЕПРИСВОЕНИЕ ПОЛЕЙ (ЕСЛИ НАДО)
ИЛИ ЖЕ ЗАПИСЬ-В-ЗАПИСЬ
Append(имя target-файла)
End
Flush(имя source-файла)
Close(имя source-файла)
Close(имя target-файла)
!---САМОЕ ГЛАВНОЕ!!!---
Lock(имя target-файла)
<проверили на 32-ю ошибку>
Build(имя target-файла)
<проверили на ошибки>
Unlock(имя target-файла)

Влёт работает. Можно отображать процесс на экране с помощью ПрогрессБара (в цикле при каждом проходе считаем переменную и путём нехитрых матвычслений получаем процент обработанных данных (общее число, естественно, берётся как Records(имя source-файла), а если обрабатывается не весь файл, то предварительно нужно подсчитать объём данных). А процесс построения ключей, занимающий тоже энное количество времени, тоже можно (при желании) отображать на ПрогрессБаре...
Ответить