Быстрое удаление записей в БД Paradox через BDE

Тема в разделе "Остальные БД", создана пользователем Bazil, 16 мар 2005.

Статус темы:
Закрыта.
  1. Bazil

    Bazil Гость

    Задача:
    Есть большая БД Paradox (.db) размером в 10 млн.записей. Доступ к БД осуществляется через BDE в среде C++Builder 5.0.
    Нужно быстро (в течение не более 10-20 сек) удалить группу в 1 млн. записей с начала БД без использования BatchMove и промежуточных БД.

    Простое решение типа
    kol=1000000;
    Table3->First();
    while(kol>0)
    { Table3->Delete();
    kol--;
    }
    работает очень медленно (около 2 минут)

    Заранее благодарен.
     
  2. Barmutik

    Barmutik Гость

    Хммм.. а как насчёт попробовать TQuery и удалить одним запросом?

    Я думаю за 5 секунд отработать должно ...
     
  3. Bazil

    Bazil Гость

    Попробовал удалить записи БД в TQuery запросом "DELETE FROM ..."
    Отработало за 9 сек !

    БОЛЬШОЕ спасибо за подсказку. :eek:
     
  4. Barmutik

    Barmutik Гость

    Как всё удачно оказалось :eek: Удачи!
     
  5. Bazil

    Bazil Гость

    Еще один вопросик по поводу удаления записей из БД ...
    После удаления записей с помощью TQuery или Table1->Delete() записи физически не удаляются, а только помечаются к удалению и размер БД остается прежним.
    Как упаковать БД через BDE или другим способом ?
     
  6. Barmutik

    Barmutik Гость

    Вобщето Paradox не помечает записи для удаления а сруза их удаляет .. помечает записи дя удаления dBase.

    ну можно попробовать вот так:

    Код (Text):
          GetMem( pTblDesc, SizeOf( CRTblDesc ));
         FillChar( pTblDesc^, SizeOf( CRTblDesc ), 0 );
         with pTblDesc^ do
         begin
          StrPCopy( szTblName, oTable.TableName );
          StrPCopy( szTblType, szParadox );
          bPack := True;
         end;
         iResult := DbiDoRestructure( oTable.DBHandle, 1,
                pTblDesc, nil, nil, nil, False );
         if iResult <> DBIERR_NONE then
         begin
          DbiGetErrorString( iResult, szErrMsg );
          MessageDlg( szErrMsg, mtError, [mbOk], 0 );
         end;
         FreeMem( pTblDesc, SizeOf( CRTblDesc ));
     
  7. Bazil

    Bazil Гость

    Barmutik

    За код спасибо, счас попробую ...

    По поводу пометки записей для удаления наверное я неправильно выразился, но могу сказать точно только одно:
    размер БД после удаления записей не уменьшается.
     
  8. Barmutik

    Barmutik Гость

    Ну и как ? Помог код?
     
  9. Bazil

    Bazil Гость

    Код почти рабочий. Почти, потому что функция DbiDoRestructure работает только с закрытой БД, а DBHandle таблицы
    можно получить только при открытой БД.
    То есть, перед использованием DbiDoRestructure нужно открыть БД, запомнить DBHandle, закрыть БД, и только потом
    вызывать DbiDoRestructure
    У меня получилось так (в переводе на C++Builder):
    Код (Text):
    #include <bde.hpp>
    hDBIDb h_db;
    DBIMSG s1;
    int err;
    ...
    // вызов
    Table1->Open();
    h_db=Table1->DBHandle;
    Table1->Close();
    err=PackTable(h_db,"my_db.db");
    if(err != DBIERR_NONE)
    { DbiGetErrorString(err, s1 );
      ShowMessage(s1);
    }


    //---------
    int PackTable(hDBIDb hDb,char *TblName)
    {
    DBIResult  rslt;
    CRTblDesc  TblDesc;

    memset((void *) &TblDesc, 0, sizeof(CRTblDesc));
    lstrcpy(TblDesc.szTblName, TblName);
    lstrcpy(TblDesc.szTblType, szPARADOX);
    TblDesc.bPack = TRUE;
    rslt = DbiDoRestructure(hDb, 1, &TblDesc, NULL, NULL, NULL, FALSE);
    return rslt;
    }
    В таком виде в отдельном приложении все работает.
    При встраивании в рабочую программу выдается ошибка "share violation", хотя БД закрыта и никем не используется
    Изменение свойства Table1->Exclusive ничего не дает.
    Перед вызовом PackTable производится удаление данных с помощью TQuery
     
  10. Bazil

    Bazil Гость

    Прошу пардону, вопрос по ошибке "share violation" закрыт, обнаружена ошибка - не был закрыт файл ...
     
Загрузка...
Статус темы:
Закрыта.

Поделиться этой страницей