zoukankan      html  css  js  c++  java
  • ado通用操作数据单元

    DELPHI开发2层C/S数据库应用程序,许多人通过ADOQUERY或ADOTABLE直接操作数据库,其实这种方法虽然最为直接,但有其缺点:如果以后要将程序升级为3层C/S会非常困难。而通过像下面的通用数据操作方法,像开发3层C/S一样地开发2层C/S程序,通过ADOQUERY或ADOTABLE获取数据,通过DATASETPROVIDER转换数据格式为OLEVARIANT,通过CLIENTDATASET内存数据集再同客户端显示控件关联,则所有操作数据的方法高度集中统一,以后要升级为多层会非常容易。这就是间接所带来的高度灵活。

    ADO不能像FIREDAC和UNIDAC一样提交联表查询的CLIENTDATASET.DELTA,这在保存类似“单据”的数据的时候很不方便,需要间接一下然后才能提交。

    FIREDAC和UNIDAC虽然默认也不支持,但只要设置属性就能获得支持。

    其中FIREDAC的设置:UpdateOptions.CheckReadOnly:=False

    其中的原由:A表联接B表查询,CLIENTDATASET中的字段既有A表的也有B表的,试图将CLIENTDATASET.delta提交给A表,CLIENTDATASET.delta将B表的字段值改变也一块打包了,而B表的字段的readonly:=true,试图提交只读字段会报错。

    unit untDB;

    interface

    uses
    System.SysUtils, System.Classes, Data.DB, Data.Win.ADODB, Datasnap.Provider,
    System.Variants, Vcl.Forms;

    type
    TfrmDB = class(TDataModule)
    ADOConnection1: TADOConnection;
    qryQuery: TADOQuery;
    DataSetProvider1: TDataSetProvider;
    qryExecute: TADOQuery;
    procedure DataModuleCreate(Sender: TObject);
    procedure qryQueryBeforeOpen(DataSet: TDataSet);
    procedure qryQueryAfterOpen(DataSet: TDataSet);
    private
    { Private declarations }
    procedure connectDB;
    public
    { Public declarations }
    function querySQL(const sql: string): OleVariant;
    function executeSQL(const sql: string): Boolean;
    function saveData(const tableName: string; delta: OleVariant): Boolean;
    function SaveDatas(tableNames, deltas: OleVariant;
    tableCount: Integer): Boolean;
    end;

    var
    frmDB: TfrmDB;

    implementation

    { %CLASSGROUP 'Vcl.Controls.TControl' }

    uses UnitWait;

    {$R *.dfm}
    { TfrmDB }

    procedure TfrmDB.connectDB;
    begin
    ADOConnection1.Close;
    ADOConnection1.ConnectionString := 'FILE NAME=' +
    ExtractFilePath(Application.ExeName) + 'db.udl';
    try
    ADOConnection1.Connected := True;
    except
    on E: Exception do
    raise Exception.Create(E.Message);
    end;
    end;

    procedure TfrmDB.DataModuleCreate(Sender: TObject);
    begin
    connectDB;
    end;

    function TfrmDB.executeSQL(const sql: string): Boolean;
    begin
    Result := False;
    if sql = '' then
    Exit;
    qryExecute.Close;
    qryExecute.sql.Clear;
    qryExecute.sql.Text := sql;
    Result := qryExecute.ExecSQL > 0;
    end;

    procedure TfrmDB.qryQueryAfterOpen(DataSet: TDataSet);
    begin
    FormWait.Close;
    FormWait.Free;
    end;

    procedure TfrmDB.qryQueryBeforeOpen(DataSet: TDataSet);
    begin
    FormWait := TFormWait.Create(Application);
    FormWait.Show;
    FormWait.Update;
    end;

    function TfrmDB.querySQL(const sql: string): OleVariant;
    begin
    Result := null;
    if sql = '' then
    Exit;
    qryQuery.Close;
    qryQuery.sql.Clear;
    qryQuery.sql.Text := sql;
    qryQuery.Open;
    Result := DataSetProvider1.Data;
    end;

    function TfrmDB.saveData(const tableName: string; delta: OleVariant): Boolean;
    var
    errCnt: Integer;
    begin
    Result := False;
    if (tableName = '') or VarIsNull(delta) then
    Exit;
    qryQuery.Close;
    qryQuery.sql.Clear;
    qryQuery.sql.Text := 'select * from ' + tableName + ' where 1=2';
    qryQuery.Open;
    DataSetProvider1.ApplyUpdates(delta, 0, errCnt);
    Result := errCnt = 0;
    end;

    function TfrmDB.SaveDatas(tableNames, deltas: OleVariant;
    tableCount: Integer): Boolean;
    var
    i, errCnt: Integer;
    begin
    if not ADOConnection1.InTransaction then
    ADOConnection1.BeginTrans; // 开启事务
    try
    for i := 0 to tableCount - 1 do
    begin
    qryQuery.Close;
    qryQuery.sql.Clear;
    qryQuery.sql.Text := 'select * from ' + tableNames[i] + ' where 1=2';
    qryQuery.Open;
    DataSetProvider1.ApplyUpdates(deltas[i], 0, errCnt);
    end;
    ADOConnection1.CommitTrans; // 提交事务
    Result := True;
    except
    ADOConnection1.RollbackTrans; // 回滚事务
    Result := False;
    end;
    end;

    end.

  • 相关阅读:
    Linux Select之坑
    BitCoin p2p通信过程
    2018软工实践——团队答辩
    Ubuntu16安装GTK+2.0教程
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    福大软工1816 · 第五次作业
    Notepad++一键编译运行(Python、Java、C++)
    福大软工1816 · 第四次作业
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/4457521.html
Copyright © 2011-2022 走看看