unit DbUtils;
interface
uses
System.Classes, System.TypInfo, System.Win.ComObj, Winapi.ActiveX, Data.DB, Data.Win.ADODB;
type
{
TMPropList class type
}
TMPropList = class(TObject)
private
FPropCount: Integer;
FPropList: PPropList;
protected
function GetPropName(x: Integer): ShortString;
function GetProp(x: Integer): PPropInfo;
public
constructor Create(aObj: TPersistent);
destructor Destroy; override;
property PropCount: Integer read FPropCount;
property PropNames[x: Integer]: ShortString read GetPropName;
property Props[x: Integer]: PPropInfo read GetProp;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbSetProxy class type
}
TDbSetProxy = class(TPersistent)
private
FDataSet: TDataSet;
FPropList: TMPropList;
FIsLoop: Boolean;
protected
procedure BeginEdit;
procedure EndEdit;
function GetInteger(x: Integer): Integer; virtual;
function GetFloat(x: Integer): Double; virtual;
function GetString(x: Integer): string; virtual;
function GetVariant(x: Integer): Variant; virtual;
procedure SetInteger(x: Integer; aValue: Integer); virtual;
procedure SetFloat(x: Integer; aValue: Double); virtual;
procedure SetString(x: Integer; aValue: string); virtual;
procedure SetVariant(x: Integer; aValue: Variant); virtual;
public
constructor Create(ds: TDataSet);
destructor Destroy; override;
procedure AfterConstruction; override;
function HasNext: Boolean;
function RecordCount: Integer;
property DataSet: TDataSet read FDataSet;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbParameter class type
}
TDbParameter = class(TObject)
private
thisKey: string;
thisValue: Variant;
thisDataType: TDataType;
thisSize: Integer;
public
constructor Create(key: string; value: Variant); overload;
constructor Create(key: string; value: Variant; dataType: TFieldType; size: Integer); overload;
function GetKey: string;
procedure SetKey(key: string);
function GetValue: Variant;
procedure SetValue(value: Variant);
function GetDataType: TDataType;
procedure SetDataType(dataType: TDataType);
function GetSize: Integer;
procedure SetSize(size: Integer);
published
property key: string read GetKey write SetKey;
property value: Variant read GetValue write SetValue;
property dataType: TDataType read GetDataType write SetDataType;
property size: Integer read GetSize write SetSize;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbOperation class type
}
TDbOperation = class(TObject)
private
{ 连接字符串 }
thisConnectionString: string;
{ 关闭Command }
procedure CloseCommand(cmd: TADOCommand);
public
{ ctor }
constructor Create(connstr: string); overload;
{ 获取一个连接 }
function GetConnection(): TADOConnection;
{ 执行单条CUD }
function ExecSQL(sql: string): Boolean; overload;
{ 执行单条CUD, 参数化 }
function ExecSQL(sql: string; parms: array of TDbParameter): Boolean; overload;
{ 批量执行CUD }
function BatchExecSQL(sqls: array of string): Boolean;
{ 获取单个值的R }
function GetSingle(sql: string): Variant; overload;
{ 获取单个值的R, 参数化 }
function GetSingle(sql: string; parms: array of TDbParameter): Variant; overload;
{ 获取一个Query对象 }
function GetQuery(sql: string): TADOQuery; overload;
{ 获取一个Query对象, 参数化 }
function GetQuery(sql: string; parms: array of TDbParameter): TADOQuery; overload;
{ 关闭Query }
procedure CloseQuery(query: TADOQuery);
{ 关闭连接 }
procedure CloseConnection(connection: TADOConnection);
{ 关闭Query及连接 }
procedure Close(query: TADOQuery; connection: TADOConnection);
end;
implementation
{
TMPropList Class implementation
}
constructor TMPropList.Create(aObj: TPersistent);
begin
FPropCount := GetTypeData(aObj.ClassInfo)^.PropCount;
FPropList := Nil;
if FPropCount > 0 then begin
GetMem(FPropList, FPropCount * SizeOf(Pointer));
GetPropInfos(aObj.ClassInfo, FPropList);
end;
end;
destructor TMPropList.Destroy;
begin
if Assigned(FPropList) then
FreeMem(FPropList);
inherited;
end;
function TMPropList.GetProp(x: Integer): PPropInfo;
begin
Result := Nil;
if (Assigned(FPropList)) then
Result := FPropList[x];
end;
function TMPropList.GetPropName(x: Integer): ShortString;
begin
Result := GetProp(x)^.Name;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbSetProxy Class implementation
}
constructor TDbSetProxy.Create(ds: TDataSet);
begin
inherited Create;
FDataSet := ds;
FDataSet.Open;
FIsLoop := false;
end;
destructor TDbSetProxy.Destroy;
var
conn: TADOConnection;
begin
FPropList.Free;
if Assigned(FDataSet) then begin
if FDataSet is TADOQuery then begin
conn := TADOQuery(FDataSet).connection;
conn.Close;
conn.Free;
conn := nil;
end;
FDataSet.Close;
FDataSet.Free;
FDataSet := nil;
end;
inherited;
end;
procedure TDbSetProxy.AfterConstruction;
begin
inherited;
FPropList := TMPropList.Create(Self);
end;
procedure TDbSetProxy.BeginEdit;
begin
if (FDataSet.State <> dsEdit) and (FDataSet.State <> dsInsert) then
FDataSet.Edit;
end;
procedure TDbSetProxy.EndEdit;
begin
if (FDataSet.State = dsEdit) or (FDataSet.State = dsInsert) then
FDataSet.Post;
end;
function TDbSetProxy.GetInteger(x: Integer): Integer;
begin
Result := FDataSet.FieldByName(FPropList.PropNames[x]).AsInteger;
end;
function TDbSetProxy.GetFloat(x: Integer): Double;
begin
Result := FDataSet.FieldByName(FPropList.PropNames[x]).AsFloat;
end;
function TDbSetProxy.GetString(x: Integer): string;
begin
Result := FDataSet.FieldByName(FPropList.PropNames[x]).AsString;
end;
function TDbSetProxy.GetVariant(x: Integer): Variant;
begin
Result := FDataSet.FieldByName(FPropList.PropNames[x]).value;
end;
procedure TDbSetProxy.SetInteger(x, aValue: Integer);
begin
BeginEdit;
FDataSet.FieldByName(FPropList.PropNames[x]).AsInteger := aValue;
end;
procedure TDbSetProxy.SetFloat(x: Integer; aValue: Double);
begin
BeginEdit;
FDataSet.FieldByName(FPropList.PropNames[x]).AsFloat := aValue;
end;
procedure TDbSetProxy.SetString(x: Integer; aValue: string);
begin
BeginEdit;
FDataSet.FieldByName(FPropList.PropNames[x]).AsString := aValue;
end;
procedure TDbSetProxy.SetVariant(x: Integer; aValue: Variant);
begin
BeginEdit;
FDataSet.FieldByName(FPropList.PropNames[x]).value := aValue;
end;
function TDbSetProxy.HasNext: Boolean;
begin
Result := not FDataSet.Eof;
if FIsLoop then begin
EndEdit;
FDataSet.Next;
Result := not FDataSet.Eof;
if not Result then begin
FDataSet.First;
FIsLoop := false;
end;
end
else if Result then begin
FIsLoop := true;
end;
end;
function TDbSetProxy.RecordCount: Integer;
begin
Result := FDataSet.RecordCount;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbParameter Class implementation
}
function TDbParameter.GetKey;
begin
Result := thisKey;
end;
procedure TDbParameter.SetKey(key: string);
begin
thisKey := key;
end;
function TDbParameter.GetValue;
begin
Result := thisValue;
end;
procedure TDbParameter.SetValue(value: Variant);
begin
thisValue := value;
end;
function TDbParameter.GetDataType;
begin
Result := thisDataType;
end;
procedure TDbParameter.SetDataType(dataType: TFieldType);
begin
thisDataType := dataType;
end;
function TDbParameter.GetSize;
begin
Result := thisSize;
end;
procedure TDbParameter.SetSize(size: Integer);
begin
thisSize := size;
end;
constructor TDbParameter.Create(key: string; value: Variant);
begin
thisKey := key;
thisValue := value;
thisDataType := ftUnknown;
thisSize := -1;
end;
constructor TDbParameter.Create(key: string; value: Variant; dataType: TFieldType; size: Integer);
begin
thisKey := key;
thisValue := value;
thisDataType := dataType;
thisSize := size;
end;
////////////////////////////////////////////////////////////////////////////////
{
TDbOperation Class implementation
}
{ 获取一个连接 }
function TDbOperation.GetConnection: TADOConnection;
var
conn: TADOConnection;
begin
conn := TADOConnection.Create(nil);
conn.ConnectionString := thisConnectionString;
conn.LoginPrompt := False;
conn.Open();
Result := conn;
end;
{ 执行单条CUD }
function TDbOperation.ExecSQL(sql: string): Boolean;
var
args: array of TDbParameter;
begin
Result := ExecSQL(sql, args);
end;
{ 执行单条CUD, 参数化 }
function TDbOperation.ExecSQL(sql: string; parms: array of TDbParameter): Boolean;
var
command: TADOCommand;
conn: TADOConnection;
parm: TDbParameter;
i: Integer;
begin
try
conn := GetConnection;
command := TADOCommand.Create(nil);
with command do begin
Connection := conn;
CommandText := sql;
for i := Low(parms) to High(parms) do begin
parm := parms[i];
Parameters.ParamByName(parm.key).value := parm.value;
if (parm.dataType <> ftUnknown) then begin
Parameters.ParamByName(parm.key).dataType := parm.dataType;
end;
if (parm.size <> -1) then begin
Parameters.ParamByName(parm.key).size := parm.size;
end;
end;
Execute;
Result := True;
end;
finally
CloseCommand(command);
CloseConnection(conn);
end;
end;
{ 批量执行CUD }
function TDbOperation.BatchExecSQL(sqls: array of string): Boolean;
var
conn: TADOConnection;
command: TADOCommand;
sql: string;
i: Integer;
begin
try
conn := GetConnection;
command := TADOCommand.Create(nil);
conn.BeginTrans;
try
with command do begin
Connection := conn;
for i := Low(sqls) to High(sqls) do begin
sql := sqls[i];
if sql <> '' then begin
CommandText := sql;
Execute;
end;
end;
end;
conn.CommitTrans;
Result := True;
except
on ex: EOleException do begin
conn.RollbackTrans;
Result := False;
end;
end;
finally
CloseCommand(command);
CloseConnection(conn);
end;
end;
{ 获取单个值的R }
function TDbOperation.GetSingle(sql: string): Variant;
var
ars: array of TDbParameter;
begin
Result := GetSingle(sql, ars);
end;
{ 获取单个值的R, 参数化 }
function TDbOperation.GetSingle(sql: string; parms: array of TDbParameter): Variant;
var
query: TADOQuery;
conn: TADOConnection;
begin
try
conn := GetConnection;
query := GetQuery(sql, parms);
if query.RecordCount < 0 then begin
Result := '';
end;
query.First;
Result := query.Fields.Fields[0].AsVariant;
finally
Close(query, conn);
end;
end;
{ 获取一个Query对象 }
function TDbOperation.GetQuery(sql: string): TADOQuery;
var
args: array of TDbParameter;
begin
Result := GetQuery(sql, args);
end;
{ 获取一个Query对象, 参数化 }
function TDbOperation.GetQuery(sql: string; parms: array of TDbParameter): TADOQuery;
var
query: TADOQuery;
parm: TDbParameter;
i: Integer;
begin
query := TADOQuery.Create(nil);
query.Connection := GetConnection;
query.SQL.Add(sql);
for i := Low(parms) to High(parms) do begin
parm := parms[i];
query.Parameters.ParamByName(parm.key).value := parm.value;
if (parm.dataType <> ftUnknown) then begin
query.Parameters.ParamByName(parm.key).dataType := parm.dataType;
end;
if (parm.size <> -1) then begin
query.Parameters.ParamByName(parm.key).size := parm.size;
end;
end;
query.Open;
Result := query;
end;
{ 关闭Query }
procedure TDbOperation.CloseQuery(query: TADOQuery);
begin
if Assigned(query) then begin
query.Close;
query.Free;
query := nil;
end;
end;
{ 关闭连接 }
procedure TDbOperation.CloseConnection(connection: TADOConnection);
begin
if Assigned(connection) then begin
connection.Close;
connection.Free;
connection := nil;
end;
end;
{ 关闭Query及连接 }
procedure TDbOperation.Close(query: TADOQuery; connection: TADOConnection);
begin
CloseQuery(query);
CloseConnection(connection);
end;
{ 关闭Command }
procedure TDbOperation.CloseCommand(cmd: TADOCommand);
begin
if Assigned(cmd) then begin
cmd.Cancel;
cmd.Free;
cmd := nil;
end;
end;
{ ctor }
constructor TDbOperation.Create(connstr: string);
begin
thisConnectionString := connstr;
end;
////////////////////////////////////////////////////////////////////////////////
initialization
CoInitialize(nil);
finalization
CoUnInitialize;
end.
内容来源于网络如有侵权请私信删除
文章来源: 博客园
- 还没有人评论,欢迎说说您的想法!