delphi 安卓 mysql delphi 自带数据库_sql

我发现很多朋友在开发数据库时都使用 Delphi 自带的 ADO 组件 或 Diamond ADO,其实在 Delphi 中使用原生 ADO 接口也是十分方便和有效的。我使用原生 ADO 开发项目已有很长一段时间,也回答过一些朋友类似的问题,现在把自己的一点心得与大家分享,班门弄斧,只是希望能对大家有所帮助。当然,这帖子也是原生的,不是转贴的。

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

一、优点

delphi 安卓 mysql delphi 自带数据库_sql


1 、大家知道 Delphi 对 ADO 接口进行了一番包装后形成了 ADOExpress,我想 Borland 的主要目的还是想与自己的数据敏感控件相连。然而事实上数据敏感控件并不是那么耀眼,如果你希望你编出来的程序稍微有点水准的话那就别用那玩意;如果你很少使用数据敏感控件,那么 ADOExpress 基本上失去了其应有的作用,无数冗余的属性、虚方法,不管你用不用得到一股脑给你编译进去,也会使你的程序再大上 200K;效率么,不说了。

delphi 安卓 mysql delphi 自带数据库_sql


2 、MSDN 和 VB 中的例子你可以搬过来就用。

delphi 安卓 mysql delphi 自带数据库_sql


3 、告诉那些 Delphi 反对者,Delphi 不是离开组件就活不了。

delphi 安卓 mysql delphi 自带数据库_sql


4 、关于代码重用:我给大家的例子都是以函数或过程形式,重用性不好么?

delphi 安卓 mysql delphi 自带数据库_sql


5 、别说帖子太长,那你看看 DB.pas, ADODB.pas 多长?

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

二、基本储备

delphi 安卓 mysql delphi 自带数据库_sql


1 、一些必须的单元

delphi 安卓 mysql delphi 自带数据库_sql

uses
   Variants, ComObj;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


2 、一些基本常数(其它查 ADODB2000.pas):

delphi 安卓 mysql delphi 自带数据库_sql


const 
  
   adOpenDynamic  
  = 
   $ 
  00000002 
  ;
   adOpenStatic  
  = 
   $ 
  00000003 
  ;

   adLockOptimistic  
  = 
   $ 
  00000003 
  ;
   adLockBatchOptimistic  
  = 
   $ 
  00000004 
  ;

   adStateClosed  
  = 
   $ 
  00000000 
  ;
   adStateOpen  
  = 
   $ 
  00000001 
  ;
   adStateConnecting  
  = 
   $ 
  00000002 
  ;
   adStateExecuting  
  = 
   $ 
  00000004 
  ;
   adStateFetching  
  = 
   $ 
  00000008 
  ;

   adUseServer  
  = 
   $ 
  00000002 
  ;
   adUseClient  
  = 
   $ 
  00000003 
  ;

   adModeReadWrite  
  = 
   $ 
  00000003 
  ;

   adXactCursorStability  
  = 
   $ 
  00001000 
  ;

   adCmdText  
  = 
   $ 
  00000001 
  ;
   adCmdTable  
  = 
   $ 
  00000002 
  ;
   adCmdStoredProc  
  = 
   $ 
  00000004 
  ;
   adCmdFile  
  = 
   $ 
  00000100 
  ;

   adAffectCurrent  
  = 
   $ 
  00000001 
  ;
   adAffectGroup  
  = 
   $ 
  00000002 
  ;
   adAffectAll  
  = 
   $ 
  00000003 
  ;
   adAffectAllChapters  
  = 
   $ 
  00000004 
  ;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


3 、一些基本函数和过程

delphi 安卓 mysql delphi 自带数据库_sql


// 
  创建 Connection 对象 
  
 
  function CreateConnection: OleVariant;
 
  // 
  释放 Connection 对象;cnn 为 Connection 对象 
  
 
  procedure FreeConnection(var cnn: OleVariant);
 
  // 
  创建 Recordset 对象 
  
 
  function CreateRecordset: OleVariant;
 
  // 
  释放 Recordset 对象;rst 为 Recordset 对象 
  
 
  procedure FreeRecordset(var rst: OleVariant);
 
  // 
  创建 Command 对象 
  
 
  function CreateCommand: OleVariant;
 
  // 
  释放 Command 对象;cmd 为 Command 对象 
  
 
  procedure FreeCommand(var cmd: OleVariant);
 
  // 
  用 Connection 连接到 SQLServer 数据库;cnn 为 Connection 对象,db 数据库名,host 主机名,usr 用户名,pwd 密码 
  
 
  function ConnectToDB(cnn: OleVariant;  
  const 
   db, host, usr, pwd:  
  string 
  ): Boolean;
 
  // 
  执行 SQL 语句,有返回行,无事务处理;cnn 为 Connection 对象,rst 为 Recordset 对象,sql 为 SQL 语句(可以是存储过程) 
  
 
  function ExecSQL(cnn, rst: OleVariant;  
  const 
   sql:  
  string 
  ): Boolean;
 
  // 
  执行 SQL 语句,无返回行,有事务处理;cnn 为 Connection 对象,cmd 为 Command 对象,sql 为 SQL 语句(可以是存储过程) 
  
 
  function ExecSQLA(cnn, cmd: OleVariant;  
  const 
   sql:  
  string 
  ): Boolean;

function CreateConnection: OleVariant;
begin

delphi 安卓 mysql delphi 自带数据库_sql

   


delphi 安卓 mysql delphi 自带数据库_sql

     Result :

= 
   CreateOleObject( 
  ' 
  ADODB.Connection 
  ' 
  );
     Result.CursorLocation : 
  = 
   adUseServer;
     Result.IsolationLevel : 
  = 
   adXactCursorStability;
     Result.Mode : 
  = 
   adModeReadWrite;
     Result.Provider : 
  = 
    
  ' 
  SQLOLEDB.1 
  ' 
  ;
   except
      
  if 
   not VarIsEmpty(Result) then Result : 
  = 
   Unassigned;
   end;
end;

procedure FreeConnection(var cnn: OleVariant);
begin
    
  if 
   not VarIsEmpty(cnn) then
   begin
      
  if 
   cnn.State  
  <> 
   adStateClosed then cnn.Close;
     cnn : 
  = 
   Unassigned;
   end;
end;

function CreateRecordset: OleVariant;
begin
    
  try 
  
     Result : 
  = 
   CreateOleObject( 
  ' 
  ADODB.Recordset 
  ' 
  );
     Result.CacheSize : 
  = 
    
  1000 
  ;
     Result.CursorType : 
  = 
   adOpenStatic;
     Result.CursorLocation : 
  = 
   adUseServer;
     Result.LockType : 
  = 
   adLockOptimistic;
   except
      
  if 
   not VarIsEmpty(Result) then Result : 
  = 
   Unassigned;
   end;
end;

procedure FreeRecordset(var rst: OleVariant);
begin
   FreeConnection(rst);
end;

function CreateCommand: OleVariant;
begin
    
  try 
  
     Result : 
  = 
   CreateOleObject( 
  ' 
  ADODB.Command 
  ' 
  );
     Result.CommandType : 
  = 
   adCmdText;
     Result.CommandTimeout : 
  = 
    
  5 
  ;
   except
      
  if 
   not VarIsEmpty(Result) then Result : 
  = 
   Unassigned;
   end;
end;

procedure FreeCommand(var cmd: OleVariant);
begin
    
  if 
   not VarIsEmpty(cmd) then cmd : 
  = 
   Unassigned;
end;

function ConnectToDB(cnn: OleVariant;  
  const 
   db, host, usr, pwd:  
  string 
  ): Boolean;
begin
   Result : 
  = 
   not VarIsEmpty(cnn);
    
  if 
   Result then
   begin
      
  if 
   cnn.State  
  <> 
   adStateClosed then cnn.Close;
     cnn.ConnectionString : 
  = 
  
        
  ' 
  Provider=SQLOLEDB.1;Persist Security Info=True;Initial Catalog= 
  ' 
    
  + 
  
       db  
  + 
    
  ' 
  ;Data Source= 
  ' 
    
  + 
   host  
  + 
    
  ' 
  ;Connect Timeout=5; 
  ' 
    
  + 
  
        
  ' 
  Use Procedure for Prepare=1 
  ' 
  ;
      
  try 
  
       cnn.Open(cnn.ConnectionString, usr, pwd,  
  - 
  1 
  );
     except
       Result : 
  = 
   False;
     end;
   end;
end;

function ExecSQL(cnn, rst: OleVariant;  
  const 
   sql:  
  string 
  ): Boolean;
begin
   Result : 
  = 
   not (VarIsEmpty(cnn) or VarIsEmpty(rst)) and (cnn.State  
  = 
   adStateOpen);
    
  if 
   Result then
   begin
      
  if 
   rst.State  
  <> 
   adStateClosed then rst.Close;
      
  try 
  
       rst.Open(sql, cnn, adOpenStatic, adLockOptimistic, adCmdText);
     except
       Result : 
  = 
   False;
     end;
   end;
end;

function ExecSQLA(cnn, cmd: OleVariant;  
  const 
   sql:  
  string 
  ): Boolean;
begin
   Result : 
  = 
   not (VarIsEmpty(cnn) or VarIsEmpty(cmd)) and (cnn.State  
  = 
   adStateOpen);
    
  if 
   Result then
   begin
     cnn.BeginTrans;
      
  try 
  
       cmd.ActiveConnection : 
  = 
   cnn;
       cmd.CommandText : 
  = 
   sql;
       cmd.Prepared : 
  = 
   True;
       cmd.Execute;
       cnn.CommitTrans;
     except
       cnn.RollbackTrans;
       Result : 
  = 
   False;
     end;
   end;
end;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

三、访问数据

delphi 安卓 mysql delphi 自带数据库_sql


1 、最前 rst.MoveFirst;

delphi 安卓 mysql delphi 自带数据库_sql


2 、最后 rst.MoveLast;

delphi 安卓 mysql delphi 自带数据库_sql


3 、向前 rst.MovePrevious;

delphi 安卓 mysql delphi 自带数据库_sql


4 、向后 rst.MoveNext;

delphi 安卓 mysql delphi 自带数据库_sql


5 、取当前记录 rst.Fields[ 0 ].Value 或 rst.Fields[ ' 字段名 ' ].Value;

delphi 安卓 mysql delphi 自带数据库_sql


6 、修改当前记录 rst.Update(rst.Fields[ 0 ].Name, 某值);

delphi 安卓 mysql delphi 自带数据库_sql


7 、取消修改 rst.CancelUpdate;

delphi 安卓 mysql delphi 自带数据库_sql


8 、删除当前记录 rst.Delete(adAffectCurrent);

delphi 安卓 mysql delphi 自带数据库_sql


9 、删除所有记录 rst.Delete(adAffectAll);

delphi 安卓 mysql delphi 自带数据库_sql


10 、追加记录

delphi 安卓 mysql delphi 自带数据库_sql

   rst.AddNew;

delphi 安卓 mysql delphi 自带数据库_sql

   rst.Fields[

0 ].Value : =  值1;

delphi 安卓 mysql delphi 自带数据库_sql

   rst.Fields[

1 ].Value : =  值2;

delphi 安卓 mysql delphi 自带数据库_sql

   rst.Update;

delphi 安卓 mysql delphi 自带数据库_sql


11 、刷新 rst.Refresh;

delphi 安卓 mysql delphi 自带数据库_sql


12 、记录数 rst.RecordCount

delphi 安卓 mysql delphi 自带数据库_sql


15 、其它方法和属性查 MSDN 或 ADO 的帮助;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

四、一些例子

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


// 
  变量声明 
  
 
  var
   cnn, rst, cmd: OleVariant;

 
  // 
  创建对象 
  
 
  procedure TForm1.FormCreate(Sender: TObject);
begin
   cnn : 
  = 
   CreateConnection;
   rst : 
  = 
   CreateRecordset;
   cmd : 
  = 
   CreateCommand;
end;

 
  // 
  释放对象 
  
 
  procedure TForm1.FormDestroy(Sender: TObject);
begin
   FreeCommand(cmd);
   FreeRecordset(rst);
   FreeConnection(cnn);
end;

 
  // 
  连接数据库 
  
 
  procedure TForm1.Button1Click(Sender: TObject);
begin
    
  if 
   ConnectToDB(cnn,  
  ' 
  mydb 
  ' 
  ,  
  ' 
  127.0.0.1 
  ' 
  ,  
  ' 
  sa 
  ' 
  ,  
  ' 
  ok 
  ' 
  ) then
     Caption : 
  = 
    
  ' 
  连接成功 
  ' 
  
    
  else 
   Caption : 
  = 
    
  ' 
  连接失败 
  ' 
  ;
end;

 
  // 
  取记录 
  
 
  procedure TForm1.Button2Click(Sender: TObject);
begin
   ExecSQL(cnn, rst,  
  ' 
  select * from 表a 
  ' 
  );
   Caption : 
  = 
   VarToStr(rst.Fields[ 
  ' 
  字段a 
  ' 
  ].Value);
end;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

五、原生 ADO 与 Delphi ADOExpress 组件的对应关系

delphi 安卓 mysql delphi 自带数据库_sql


1 
  、Connection  
  <=> 
   ADOConnection.ConnectionObject;
 
  2 
  、Recordset  
  <=> 
   ADODataSet.Recordset;
 
  3 
  、Command  
  <=> 
   ADOCommand.CommandObject;
 
  4 
  、 
  ? 
    
  <=> 
   ADOQuery,因为 ADOQuery 根本就不是原生 ADO 对象 
 
  5 
  、ExecSQL  
  <=> 
   ADODataSet.Open;
 
  6 
  、ExecSQLA  
  <=> 
   ADOCommand.Execute;
 
  7 
  、有了上面几个其它的就不多说了

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

六、与数据库结构有关的一些函数

delphi 安卓 mysql delphi 自带数据库_sql


1 、动态改变字段名称

delphi 安卓 mysql delphi 自带数据库_sql

uses ComObj;
 
  // 
  Access
 
  // 
  TableName: 表名; OldColName: 原字段名; NewColName: 新字段名; 
  
 
  procedure RenameField( 
  const 
   TableName, OldColName, NewColName:  
  string 
  );
var
   DB, Col: OleVariant;
begin
   DB : 
  = 
   CreateOleObject( 
  ' 
  ADOX.Catalog 
  ' 
  );
   DB.ActiveConnection : 
  = 
   ADOConnection1.ConnectionObject;
   Col : 
  = 
   CreateOleObject( 
  ' 
  ADOX.Column 
  ' 
  );
   Col : 
  = 
   DB.Tables[TableName].Columns[OldColName];
   Col.Name : 
  = 
   NewColName;
end;

 
  // 
  SQLServer 
  
 
  procedure RenameField( 
  const 
   TableName, OldColName, NewColName:  
  string 
  );
begin
   with ADOCommand1  
  do 
  
   begin
     CommandText : 
  = 
    
  ' 
  EXEC sp_rename  
  ''' 
    
  + 
   TableName  
  + 
    
  ' 
  . 
  ' 
    
  + 
   OldColName  
  + 
   
        
  ''' 
  , 
  ''' 
    
  + 
   NewColName  
  + 
    
  ''' 
  , 
  '' 
  COLUMN 
  '' 
  ; 
  ' 
  ;
     Excute;
   end;
end;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


2 、取得 Access 库中的表结构

delphi 安卓 mysql delphi 自带数据库_sql

type
   TTableDef  
  = 
   record
     Name,
     DateCreated,
     LastUpdated,
     Description:  
  string 
  ;
   end;

   TTableDefs  
  = 
   array of TTableDef;

procedure GetTableDefs( 
  const 
   DBName:  
  string 
  ;  
  out 
   TableDefs: TTableDefs);
var
   DBEngine, DB: OleVariant;
   I: Longint;
begin
    
  try 
  
     DBEngine : 
  = 
   CreateOleObject( 
  ' 
  DAO.DBEngine.36 
  ' 
  );
     DB : 
  = 
   DBEngine.OpenDatabase(DBName);
     SetLength(TableDefs, Longint(DB.TableDefs.Count));
      
  for 
   I : 
  = 
   Low(TableDefs) to High(TableDefs)  
  do 
  
     begin
       TableDefs[I].Name : 
  = 
   DB.TableDefs[I].Name;
       TableDefs[I].DateCreated : 
  = 
   DB.TableDefs[I].DateCreated;
       TableDefs[I].LastUpdated : 
  = 
   DB.TableDefs[I].LastUpdated;
        
  try 
  
         TableDefs[I].Description : 
  = 
   DB.TableDefs[I].Properties[ 
  ' 
  Description 
  ' 
  ].Value;
       except
         TableDefs[I].Description : 
  = 
    
  '' 
  ;
       end;
     end;
    
  finally 
  
     DB : 
  = 
   Unassigned;
     DBEngine : 
  = 
   Unassigned;
   end;
end;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


3 、取得 Access 表中的字段结构

delphi 安卓 mysql delphi 自带数据库_sql

type
   TFieldDef  
  = 
   record
     Name:  
  string 
  ;
     Types,
     Size: Longint;
     Description:  
  string 
  ;
   end;

   TFieldDefs  
  = 
   array of TFieldDef;

procedure GetFieldDefs( 
  const 
   DBName, TableName:  
  string 
  ;  
  out 
   FieldDefs: TFieldDefs);
var
   DBEngine, DB: OleVariant;
   I: Longint;
begin
    
  try 
  
     DBEngine : 
  = 
   CreateOleObject( 
  ' 
  DAO.DBEngine.36 
  ' 
  );
     DB : 
  = 
   DBEngine.OpenDatabase(DBName);
     SetLength(FieldDefs, Longint(DB.TableDefs[TableName].Fields.Count));
      
  for 
   I : 
  = 
   Low(FieldDefs) to High(FieldDefs)  
  do 
  
     begin
       FieldDefs[I].Name : 
  = 
   DB.TableDefs[TableName].Fields[I].Name;
       FieldDefs[I].Types : 
  = 
   DB.TableDefs[TableName].Fields[I].Type;
       FieldDefs[I].Size : 
  = 
   DB.TableDefs[TableName].Fields[I].Size;
        
  try 
  
         FieldDefs[I].Description : 
  = 
   DB.TableDefs[TableName].Fields[I].Properties[ 
  ' 
  Description 
  ' 
  ].Value;
       except
         FieldDefs[I].Description : 
  = 
    
  '' 
  ;
       end;
     end;
    
  finally 
  
     DB : 
  = 
   Unassigned;
     DBEngine : 
  = 
   Unassigned;
   end;
end;

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql


4 、至于如何动态创建 Access 数据库之类我就不罗嗦了,到处都有相关的月经贴

delphi 安卓 mysql delphi 自带数据库_sql


delphi 安卓 mysql delphi 自带数据库_sql

七、其它

delphi 安卓 mysql delphi 自带数据库_sql


1 、我使用 ADO 的经历:ADOExpress --> ADOExpress的原生接口 --> 引用ADO2.1接口单元,即ADODB_TLB --> 直接使用 ADO 的 COM 接口;

delphi 安卓 mysql delphi 自带数据库_sql


2 、希望此贴能对朋友门有所帮助,我写的这些都是经过实战检验的;

delphi 安卓 mysql delphi 自带数据库_sql


3 、觉得有用的朋友可以试一下,如果觉得没用就当我没写,耽误你时间了。