• 使用原生ADO编程


    {*******************************************************}
    {                                                       }
    {       原生ADO                                         }
    {                                                       }
    {       版权所有 (C) 2008 咏南工作室(陈新光)            }
    {                                                       }
    {*******************************************************}

    unit uADO;

    interface

    uses
      Variants,ComObj;

    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;

    //创建 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;

    implementation

    function CreateConnection: OleVariant;
    begin
      try
        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;

    end.

    三、访问数据
    1、最前 rst.MoveFirst;
    2、最后 rst.MoveLast;
    3、向前 rst.MovePrevious;
    4、向后 rst.MoveNext;
    5、取当前记录 rst.Fields[0].Value 或 rst.Fields['字段名'].Value;
    6、修改当前记录 rst.Update(rst.Fields[0].Name, 某值);
    7、取消修改 rst.CancelUpdate;
    8、删除当前记录 rst.Delete(adAffectCurrent);
    9、删除所有记录 rst.Delete(adAffectAll);
    10、追加记录
      rst.AddNew;
      rst.Fields[0].Value := 值1;
      rst.Fields[1].Value := 值2;
      rst.Update;
    11、刷新 rst.Refresh;
    12、记录数 rst.RecordCount
    15、其它方法和属性查 MSDN 或 ADO 的帮助;

    四、一些例子

    //变量声明
    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
      if ExecSQL(cnn, rst, 'select * from 表a') then
        Caption := VarToStr(rst.Fields['字段a'].Value);
    end;

    五、原生 ADO 与 Delphi ADOExpress 组件的对应关系
    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、有了上面几个其它的就不多说了

    六、与数据库结构有关的一些函数
    1、动态改变字段名称
    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;

    2、取得 Access 库中的表结构
    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;

    3、取得 Access 表中的字段结构
    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;
     

  • 相关阅读:
    按照步长切图
    labelme标记的.json转换成图片
    具有中文名称图片格式的读取
    如何用labelme标注图片产生box训练
    weblogic修改密码&密码重置
    Oracle中统计数据占用空间大小
    Maven篇----10 常见问题记录
    Maven篇----09 一些有趣的特性使用
    Maven篇----08 pom.xml详解
    Maven篇----07 如何将普通java项目转换为maven项目
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/2940893.html
Copyright © 2020-2023  润新知