Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Delphi: Общие вопросы > Срочно: Сжатие базы данных


Автор: Pakshin A. S. 1.4.2004, 20:13
В MS Accesse есть сжатие базы данных. Мне надо сотворить это средствами Delphi exclamation.gif : SQL или что-нибудь в этом роде.

Времени нет, так что благодарен за чёткое руководство или исходник. biggrin.gif

Работаю через ADO.

Автор: December 1.4.2004, 22:07
Насколько я знаю, SQL не поддерживает архивацию никоим раком. В дельфи встроенных средств не встречал. Есть куча третьесторонних компонентов, которые этим занимаются, но у них бесплатные только триалы или персональные версии.

Автор: javas 1.4.2004, 23:21
Здесь понятие сжатие не означает архивацию, а означает физическое удаление логически удаленных записей.

Автор: December 2.4.2004, 03:29
А! Дык, кажется, кроме xBase, никто удалённые записи не хранит! А для вышеупомянутых -
Код

FileStorage:TTable;
...
procedure PackTable;
begin
try
Check(dbiPackTable(form1.FileStorage.DBHandle,form1.FileStorage.Handle,nil,nil,true));
except
showmessage('Error packing the base!');
end;{except}
end;{PackTable}

Автор: Pakshin A. S. 2.4.2004, 18:07
Цитата

[Error] Unit1.pas(30): Undeclared identifier: 'Check'
[Error] Unit1.pas(30): Undeclared identifier: 'DBHandle'
[Error] Unit1.pas(30): Undeclared identifier: 'Handle'
[Fatal Error] Project1.dpr(5): Could not compile used unit 'Unit1.pas'


У меня TADOTable exclamation.gif

Автор: December 2.4.2004, 23:36
Ты в хелпе функцию нашёл?

Автор: Pakshin A. S. 5.4.2004, 08:16
Ага, на не совсем допёр, к сожалению.

Спешка уже не нужна, так что если будет время, черкните ответ...

Автор: December 6.4.2004, 01:43
В общем так. Возможность сжатия есть в dBase (там запись можно ещё и восстановить после удаления) и Paradox (можно только очистить пустые места). С остальными СУБД в этом плане не сталкивался. В зависимости от того, с чем ты работаешь, надо использовать разные функции. Для dBase я уже привёл, для парадокса - смотри код модуля. Это листинг из книжки Тейсейры и Пачеко "Дельфи 5". Чё будет непонятно - спрашивай, текст у меня есть.
Цитата
unit DDGTbls;

interface

uses DB, DBTables, BDE;

type
  TdBaseTable = class(TTable)
  private
    FViewDeleted: Boolean;
    function GetIsDeleted: Boolean;
    function GetRecNum: Longint;
    procedure SetViewDeleted(Value: Boolean);
  protected
    function CreateHandle: HDBICur; override;
  public
    procedure Pack(RegenIndexes: Boolean);
    procedure UndeleteRecord;
    property IsDeleted: Boolean read GetIsDeleted;
    property RecNum: Longint read GetRecNum;
    property ViewDeleted: Boolean read FViewDeleted write SetViewDeleted;
  end;

  TParadoxTable = class(TTable)
  private
  protected
    function CreateHandle: HDBICur; override;
    function GetRecNum: Longint;
  public
    procedure Pack;
    property RecNum: Longint read GetRecNum;
  end;

implementation

uses SysUtils;

{ TdBaseTable }

function TdBaseTable.GetIsDeleted: Boolean;
{ Returns a boolean indicating whether or not the current record }
{ has been soft deleted. }
var
  RP: RECProps;
begin
  if not FViewDeleted then    // don't bother if they aren't viewing
    Result := False            // deleted records
  else begin
    UpdateCursorPos;          // update BDE from Delphi
    { Get current record properties }
    Check(dbiGetRecord(Handle, dbiNOLOCK, Nil, @RP));
    Result := RP.bDeleteFlag;  // return flag from properties
  end;
end;

function TdBaseTable.GetRecNum: Longint;
{ Returns the physical record number of the current record. }
var
  RP: RECProps;
begin
  UpdateCursorPos;            // update BDE from Delphi
  { Get current record properties }
  Check(dbiGetRecord(Handle, dbiNOLOCK, Nil, @RP));
  Result := RP.iPhyRecNum;    // return value from properties
end;

function TdBaseTable.CreateHandle: HDBICur;
{ Overridden from ancestor in order to perform a check to }
{ ensure that this is a dBASE table. }
var
  CP: CURProps;
begin
  Result := inherited CreateHandle;        // do inherited
  if Result <> Nil then begin
    { Get cursor properties, and raise exception if the }
    { table isn't using the dBASE driver. }
    Check(dbiGetCursorProps(Result, CP));
    if not (CP.szTableType = szdBASE) then
      raise EDatabaseError.Create('Not a dBASE table');
  end;
end;

procedure TdBaseTable.Pack(RegenIndexes: Boolean);
{ Packs the table in order to removed soft deleted records }
{ from the file. }
const
  SPackError = 'Table must be active and opened exclusively';
begin
  { Table must be active and opened exclusively }
  if not (Active and Exclusive) then
    raise EDatabaseError.Create(SPackError);
  try
    { Pack the table }
    Check(dbiPackTable(DBHandle, Handle, Nil, Nil, RegenIndexes));
  finally
    { update Delphi from BDE }
    CursorPosChanged;
    Refresh;
  end;
end;

procedure TdBaseTable.SetViewDeleted(Value: Boolean);
{ Allows the user to toggle between viewing and not viewing }
{ deleted records. }
begin
  { Table must be active }
  if Active and (FViewDeleted <> Value) then begin
    DisableControls;    // avoid flicker
    try
      { Magic BDE call to toggle view of soft deleted records }
      Check(dbiSetProp(hdbiObj(Handle), curSOFTDELETEON, Longint(Value)));
    finally
      Refresh;          // update Delphi
      EnableControls;    // flicker avoidance complete
    end;
    FViewDeleted := Value
  end;
end;

procedure TdBaseTable.UndeleteRecord;
begin
  if not IsDeleted then
    raise EDatabaseError.Create('Record is not deleted');
  Check(dbiUndeleteRecord(Handle));
  Refresh;
end;

function TParadoxTable.CreateHandle: HDBICur;
{ Overridden from ancestor in order to perform a check to }
{ ensure that this is a Paradox table. }
var
  CP: CURProps;
begin
  Result := inherited CreateHandle;        // do inherited
  if Result <> Nil then begin
    { Get cursor properties, and raise exception if the }
    { table isn't using the Paradox driver. }
    Check(dbiGetCursorProps(Result, CP));
    if not (CP.szTableType = szPARADOX) then
      raise EDatabaseError.Create('Not a Paradox table');
  end;
end;

function TParadoxTable.GetRecNum: Longint;
{ Returns the sequence number of the current record. }
begin
  UpdateCursorPos;            // update BDE from Delphi
  { Get sequence number of current record into Result }
  Check(dbiGetSeqNo(Handle, Result));
end;

procedure TParadoxTable.Pack;
var
  TblDesc: CRTblDesc;
  TempDBHandle: HDBIDb;
  WasActive: Boolean;
begin
  { Initialize TblDesc record }
  FillChar(TblDesc, SizeOf(TblDesc), 0); // fill with 0s
  with TblDesc do begin
    StrPCopy(szTblName, TableName);      // set table name
    szTblType := szPARADOX;              // set table type
    bPack := True;                      // set pack flag
  end;
  { Store table active state.  Must close table to pack. }
  WasActive := Active;
  if WasActive then Close;
  try
    { Create a temporary database.  Must be read-write/exclusive }
    Check(dbiOpenDatabase(PChar(DatabaseName), Nil, dbiREADWRITE,
          dbiOpenExcl, Nil, 0, Nil, Nil, TempDBHandle));
    try
      { Pack the table }
      Check(dbiDoRestructure(TempDBHandle, 1, @TblDesc, Nil, Nil, Nil,
            False));
    finally
      { Close the temporary database }
      dbiCloseDatabase(TempDBHandle);
    end;
  finally
    { Reset table active state }
    Active := WasActive;
  end;
end;

end.

Автор: Pakshin A. S. 6.4.2004, 08:44
Эту штуку я знаю, но работать с Access не хочет, что и есть истина. Просто в самом Access'e есть фенкция Сервис->Служебные программы->Сжать и восстановить базу данных. Это откопал в MS Access 2002, может это только здесь появилось.

Автор: Napalm 7.4.2004, 16:19
пользуйся поиском. я вот http://forum.vingrad.ru/index.php?showtopic=19921это писал. как раз на делфях smile.gif

Автор: Pakshin A. S. 7.4.2004, 18:31
Спасибо!!!

Как я понял olddb можно сжимать в newdb, а в саму себя, т. е. olddb в olddb, нельзя... жалко, будет время тратиться на переписывание и на удаление...

Автор: Napalm 8.4.2004, 10:32
к сожалению ты прав. но так придумали разработчики. и еще момент... если до сжатия база самим аксесом открывается без проблем, то после такого сжатия аксесс не может определить формат, но на работе из делфей это никак не сказывается. т.е. все по прежнему работает нормально

Автор: Pakshin A. S. 8.4.2004, 13:51
Ну Access меня не волнует, тем более так какового его у меня нет...

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