首页  编辑  

对access数据库维护

Tags: /超级猛料/Database.数据库相关/ODBC、ADO、Access/   Date Created:

{***************************************************************

*

* Unit Name: unAccessTools

* Purpose  : Provide tools to compact and repair Access database.

*

****************************************************************}

unit unAccessTools;

interface

uses Sysutils,ComObj,Dialogs;

function DaoActive(var DaoObject:OleVariant):Boolean;

function DaoCompactDB(const FileName:string):Boolean;

function DaoRepairDB(const FileName:string):Boolean;

implementation

function DaoActive(var DaoObject:OleVariant):Boolean;

begin

 Result:=False;

 try

   DaoObject:=GetActiveOleObject('DAO.DBEngine.36');

   Result:=True;

 except

   try

     DaoObject:=CreateOleObject('DAO.DBEngine.36');

     Result:=True;

   except

     DaoObject:=Null;

   end;

 end;

end;

//压缩Access数据库

function DaoCompactDB(const FileName:string):Boolean;

var

 db:OleVariant;

 TempFile:string;

begin

 Result:=False;

 try

   if not DaoActive(db) then

     Exit;

   try

     TempFile:=ExtractFilePath(FileName)+'msaTemp.mdb';

     db.CompactDatabase(FileName,TempFile);

     DeleteFile(FileName);

     RenameFile(TempFile,FileName);

     Result:=True;

   except

     on E:EOleException do

       ShowMessage(E.Message);

   end

 finally

   db:=Unassigned;

 end;

end;

//修复Access数据库

function DaoRepairDB(const FileName:string):Boolean;

var

 db:OleVariant;

begin

 Result:=False;

 try

   if not DaoActive(db) then

     Exit;

   try

     db.RepairDatabase(FileName);

     Result:=True;

   except

     on E:EOleException do

       ShowMessage(E.Message);

   end

 finally

   db:=Unassigned;

 end;

end;

end.

---------------------------------------

1.DELPHI 中操作 ACCESS 数据库 ( 建立 .mdb 文件 , 压缩数据库 )

以下代码在 WIN2K,D6,MDAC2.6 下测试通过 ,

编译好的程序在 WIN98 第二版无 ACCESS 环境下运行成功 .

// 在之前 uses ComObj,ActiveX

// 声明连接字符串

Const

SConnectionString       = 'Provider=Microsoft.Jet.OLEDB.4.0;Data Source=%s;'

                              +'Jet OLEDB:Database Password=%s;';

//=============================================================================

// Procedure: GetTempPathFileName

// Author   : ysai

// Date     : 2003-01-27

// Arguments: (None)

// Result   : string

//=============================================================================

function GetTempPathFileName():string;

// 取得临时文件名

var

SPath,SFile:array [0..254] of char;

begin

GetTempPath(254,SPath);

GetTempFileName(SPath,'~SM',0,SFile);

result:=SFile;

DeleteFile(PChar(result));

end;

//=============================================================================

// Procedure: CreateAccessFile

// Author   : ysai

// Date     : 2003-01-27

// Arguments: FileName:String;PassWord:string=''

// Result   : boolean

//=============================================================================

function CreateAccessFile(FileName:String;PassWord:string=''):boolean;

// 建立 Access 文件,如果文件存在则失败

var

STempFileName:string;

vCatalog:OleVariant;

begin

STempFileName:=GetTempPathFileName;

try

  vCatalog:=CreateOleObject('ADOX.Catalog');

  vCatalog.Create(format(SConnectionString,[STempFileName,PassWord]));

  result:=CopyFile(PChar(STempFileName),PChar(FileName),True);

  DeleteFile(STempFileName);

except

  result:=false;

end;

end;

//=============================================================================

// Procedure: CompactDatabase

// Author   : ysai

// Date     : 2003-01-27

// Arguments: AFileName,APassWord:string

// Result   : boolean

//=============================================================================

function CompactDatabase(AFileName,APassWord:string):boolean;

// 压缩与修复数据库 , 覆盖源文件

var

STempFileName:string;

vJE:OleVariant;

begin

STempFileName:=GetTempPathFileName;

try

  vJE:=CreateOleObject('JRO.JetEngine');

  vJE.CompactDatabase(format(SConnectionString,[AFileName,APassWord]),

      format(SConnectionString,[STempFileName,APassWord]));

  result:=CopyFile(PChar(STempFileName),PChar(AFileName),false);

  DeleteFile(STempFileName);

except

  result:=false;

end;

end;

//=============================================================================

// Procedure: ChangeDatabasePassword

// Author   : ysai

// Date     : 2003-01-27

// Arguments: AFileName,AOldPassWord,ANewPassWord:string

// Result   : boolean

//=============================================================================

function ChangeDatabasePassword(AFileName,AOldPassWord,ANewPassWord:string):boolean;

// 修改 ACCESS 数据库密码

var

STempFileName:string;

vJE:OleVariant;

begin

STempFileName:=GetTempPathFileName;

try

  vJE:=CreateOleObject('JRO.JetEngine');

  vJE.CompactDatabase(format(SConnectionString,[AFileName,AOldPassWord]),

      format(SConnectionString,[STempFileName,ANewPassWord]));

  result:=CopyFile(PChar(STempFileName),PChar(AFileName),false);

  DeleteFile(STempFileName);

except

  result:=false;

end;

end;

2.ACCESS 中使用 SQL 语句应注意的地方及几点技巧

以下 SQL 语句在 ACCESS XP 的查询中测试通过

建表 :

  Create Table Tab1 (

      ID Counter,

      Name string,

      Age integer,

      [Date] DateTime);

技巧 :

  自增字段用 Counter 声明 .

  字段名为关键字的字段用方括号 [] 括起来 , 数字作为字段名也可行 .

建立索引 :

  下面的语句在 Tab1 Date 列上建立可重复索引

  Create Index iDate ON Tab1 ([Date]);

  完成后 ACCESS 中字段 Date 索引属性显示为 - ( 有重复 ).

  下面的语句在 Tab1 Name 列上建立不可重复索引

  Create Unique Index iName ON Tab1 (Name);

  完成后 ACCESS 中字段 Name 索引属性显示为 - ( 无重复 ).

  下面的语句删除刚才建立的两个索引

  Drop Index iDate ON Tab1;

  Drop Index iName ON Tab1;

ACCESS SQLSERVER 中的 UPDATE 语句对比 :

  SQLSERVER 中更新多表的 UPDATE 语句 :

  UPDATE Tab1

  SET a.Name = b.Name

  FROM Tab1 a,Tab2 b

  WHERE a.ID = b.ID;

  同样功能的 SQL 语句在 ACCESS 中应该是

  UPDATE Tab1 a,Tab2 b

  SET a.Name = b.Name

  WHERE a.ID = b.ID;

:ACCESS 中的 UPDATE 语句没有 FROM 子句 , 所有引用的表都列在 UPDATE 关键字后 .

上例中如果 Tab2 可以不是一个表 , 而是一个查询 , :

  UPDATE Tab1 a,(Select ID,Name From Tab2) b

  SET a.Name = b.Name

  WHERE a.ID = b.ID;

访问多个不同的 ACCESS 数据库 - SQL 中使用 In 子句 :

  Select a.*,b.* From Tab1 a,Tab2 b In 'db2.mdb' Where a.ID=b.ID;

  上面的 SQL 语句查询出当前数据库中 Tab1 db2.mdb( 当前文件夹中 ) Tab2 ID 为关联的所有记录 .

缺点 - 外部数据库不能带密码 .

补充 : 看到 ugvanxk 在一贴中的答复 , 可以用

  Select * from [c:\aa\a.mdb;pwd=1111].table1;

ACCESS XP 测试通过

ACCESS 中访问其它 ODBC 数据源

下例在 ACCESS 中查询 SQLSERVER 中的数据

  SELECT * FROM Tab1 IN [ODBC]

  [ODBC;Driver=SQL Server;UID=sa;PWD=;Server=127.0.0.1;DataBase=Demo;]

外部数据源连接属性的完整参数是 :

  [ODBC;DRIVER=driver;SERVER=server;DATABASE=database;UID=user;PWD=password;]

其中的 DRIVER=driver 可以在注册表中的

  HKEY_LOCAL_MACHINE\SOFTWARE\ODBC\ODBCINST.INI\

中找到

异构数据库之间导数据参见 碧血剑

http://www.delphibbs.com/delphibbs/dispq.asp?lid=1691966

ACCESS 支持子查询

ACCESS 支持外连接 , 但不包括完整外部联接 , 如支持

  LEFT JOIN RIGHT JOIN

但不支持

  FULL OUTER JOIN FULL JOIN

ACCESS 中的日期查询

注意 :ACCESS 中的日期时间分隔符是 # 而不是引号

  Select * From Tab1 Where [Date]>#2002-1-1#;

DELPHI 中我这样用

  SQL.Add(Format(

      'Select * From Tab1 Where [Date]>#%s#;',

      [DateToStr(Date)]));

ACCESS 中的字符串可以用双引号分隔 , SQLSERVER 不认 , 所以为了迁移方便和兼容 ,

建议用单引号作为字符串分隔符