本文整理自网络,侵删。
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
usesSystem.SysUtils, System.Classes, Data.DB, Data.Win.ADODB, Datasnap.Provider,System.Variants, Vcl.Forms;
typeTfrmDB = 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;
varfrmDB: TfrmDB;
implementation
{ %CLASSGROUP 'Vcl.Controls.TControl' }
uses UnitWait;
{$R *.dfm}{ TfrmDB }
procedure TfrmDB.connectDB;beginADOConnection1.Close;ADOConnection1.ConnectionString := 'FILE NAME=' +ExtractFilePath(Application.ExeName) + 'db.udl';tryADOConnection1.Connected := True;excepton E: Exception doraise Exception.Create(E.Message);end;end;
procedure TfrmDB.DataModuleCreate(Sender: TObject);beginconnectDB;end;
function TfrmDB.executeSQL(const sql: string): Boolean;beginResult := False;if sql = '' thenExit;qryExecute.Close;qryExecute.sql.Clear;qryExecute.sql.Text := sql;Result := qryExecute.ExecSQL > 0;end;
procedure TfrmDB.qryQueryAfterOpen(DataSet: TDataSet);beginFormWait.Close;FormWait.Free;end;
procedure TfrmDB.qryQueryBeforeOpen(DataSet: TDataSet);beginFormWait := TFormWait.Create(Application);FormWait.Show;FormWait.Update;end;
function TfrmDB.querySQL(const sql: string): OleVariant;beginResult := null;if sql = '' thenExit;qryQuery.Close;qryQuery.sql.Clear;qryQuery.sql.Text := sql;qryQuery.Open;Result := DataSetProvider1.Data;end;
function TfrmDB.saveData(const tableName: string; delta: OleVariant): Boolean;varerrCnt: Integer;beginResult := False;if (tableName = '') or VarIsNull(delta) thenExit;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;vari, errCnt: Integer;beginif not ADOConnection1.InTransaction thenADOConnection1.BeginTrans; // 开启事务tryfor i := 0 to tableCount - 1 dobeginqryQuery.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;exceptADOConnection1.RollbackTrans; // 回滚事务Result := False;end;end;
end.
https://www.cnblogs.com/hnxxcxg/p/4457521.html
相关阅读 >>
Delphi firemonkey 学习笔记 �c tpopup 控件的使用
更多相关阅读请进入《Delphi》频道 >>