• 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.

  • 相关阅读:
    第 45 届国际大学生程序设计竞赛(ICPC)亚洲区域赛(上海)M . Gitignore(模拟)
    11.FreeRTOS延时函数
    10.FreeRTOS任务通知的简易分析
    9.FreeRTOS内存管理简易分析
    8. FreeRTOS信号量的简易分析
    7.FreeRTOS 队列的简易分析
    6. FreeRTOS任务调度
    5.FreeRTOS任务切换的简易分析
    4.FreeRTOS调度器的启动简易分析
    3.FreeRTOS任务的简易分析
  • 原文地址:https://www.cnblogs.com/hnxxcxg/p/4457521.html
Copyright © 2020-2023  润新知