思路:中間層與客戶端通過三個關鍵的接口過程進行交互操作(GetData,SetData,GetspData)
GetData:獲取數據集。客戶端傳遞數據集名稱給中間層,中間層根據請求的數據集名稱從數據庫的配置文件中獲取相關信息,與客戶的的條件集合一起給合成SQL語句
SetData:提交數據集。客戶端傳遞修改後的數據集Delta與名稱給中間層,中間層根據請求的數據集名稱從數據庫的配置文件中獲取相關信息,然後解釋Delta並執行相關規則進行數據更新
GetRecStrs:獲取下拉列表信息
GetspData:執行存儲過程,並返回結果集
ExecProd:執行存儲過程,返回提示信息
優點:
因爲獲取數據與更新數據過程的配置文件在存儲在數據庫中,那麼更改與配置更爲靈活,對SQL語句不再存在限據,對權限方面可進行更格的控制(達到錄入記錄控制)
數據提交時使用自定義更新過程,無論從速度、控制、安全等方面來說,都不是一件壞事(能使用附加工具快速生成標準的存儲過程與配置信息)
維護簡單,更新業務邏輯時僅需更新相應的存儲過程中,無需更改中間層與客戶端
能應付多變的系統開發過程,即使系統的流程或邏輯發生重大變更修改也相當簡單,尤其是在需求不是相當明確的時候(有幾個系統在上線實施之前能做到需求明細呢?^_^)
缺點:
即使系統再簡單,若僅存在一個窗體的話,也必須將基類架設完整,與書本上一般開發過程存在差異,新手需一週左右時候才能上手
中間層代碼:
/////***********************************************************///
/////單元文件 U_RDM.pas
unit U_RDM;
{$WARN SYMBOL_PLATFORM OFF}
interface
uses
Windows, Messages, SysUtils, Classes, ComServ, ComObj, VCLCom, DataBkr,
DBClient, MRPManange_TLB, StdVcl, DB, ADODB, Provider, Variants, StrUtils;
type
THPMRP = class(TRemoteDataModule, IHPMRP)
sp_Pub_Ref: TADOStoredProc;
get_Q_RecStrs: TADOQuery;
BesConnection: TADOConnection;
TmpCDS: TClientDataSet;
tmpdsp: TDataSetProvider;
Q_tmp: TADOQuery;
sp_get_apply: TADOStoredProc;
sp_get_spNm: TADOStoredProc;
dsp_get_spQuery: TDataSetProvider;
sp_get_Data: TADOStoredProc;
sp_exec: TADOStoredProc;
procedure RemoteDataModuleCreate(Sender: TObject);
private { Private declarations }
app_dspName, app_spName: String; //提交更新的dsp 控件名 調用過程名
app_ChkNull, app_ParameStr, app_ParamSet: WideString; //不爲空約束,更新參數
Procedure LoginServer;
Function GetSQL(UserID, dstNm, Corp_No, Cust_No, swhExpr: WideString; ParamStr: OleVariant): WideString; //取數據語句
Function CannotNull(FieldStr: String; DeltaDS:TCustomClientDataSet; UpdKind: String=''): String; //不爲空校驗
Function UpdKindStr(var Kind: TUpdateKind): String; //數據更改的狀態:Ins, Upd, Del
Function SetspParam(spName:String; DeltaDS:TCustomClientDataSet; //存儲過程更新數據
ParameStr,ParamSet:WideString; UpdKind: String=''): WideString;
procedure PubBeforeUpdateRecord(Sender: TObject; //數據提交公用過程
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet;
UpdateKind: TUpdateKind; var Applied: Boolean);
Function SetspParameters(UserID, dstNm: String; ParamStr: OleVariant; run_sp_Nm: TADOStoredProc): Boolean;
Function varTypeCntInt(varType: TDataType): Integer;
protected
class procedure UpdateRegistry(Register: Boolean; const ClassID, ProgID: string); override;
procedure GetRecStrs(const UserID, Corp_No, TabName, ColName,
ExprStr: WideString; out RstStrs: OleVariant); safecall;
function GetData(const UserID, dstNm, Corp_No, Cust_No: WideString;
ParamStr: OleVariant; const sExpr: WideString): OleVariant; safecall;
function SetData(const UserID, dstNm, ParamStr: WideString;
vData: OleVariant): OleVariant; safecall;
function GetAuth(const UserID, dstNm, GrpTyp: WideString): OleVariant;
safecall;
function GetspData(const UserID, dstNm: WideString;
ParamStr: OleVariant): OleVariant; safecall;
procedure GetColStrs(const UserID, Corp_No, TabName, ColName,
ExprStr: WideString; out RstStrs: OleVariant); safecall;
function ExecProc(const UserID, Corp_No, dstNm: WideString;
ParamStr: OleVariant): Shortint; safecall;
public { Public declarations }
end;
implementation
uses U_PublicFun, U_MRPServer;
{$R *.DFM}
class procedure THPMRP.UpdateRegistry(Register: Boolean; const ClassID, ProgID: string);
begin
if Register then
begin
inherited UpdateRegistry(Register, ClassID, ProgID);
EnableSocketTransport(ClassID);
EnableWebTransport(ClassID);
end else
begin
DisableSocketTransport(ClassID);
DisableWebTransport(ClassID);
inherited UpdateRegistry(Register, ClassID, ProgID);
end;
end;
{ 創建數據模塊數據庫連接 BES96261 }
Procedure THPMRP.LoginServer;
begin
BESConnection.Connected := False;
BESConnection.ConnectionString := GetServerConnetionStr;
BESConnection.Connected := True;
end;
procedure THPMRP.RemoteDataModuleCreate(Sender: TObject);
var I: Integer;
begin
LoginServer;
{ 使用自定義更新過程 }
For I := 0 to self.ComponentCount - 1 do
begin
If (Components[I] is TDataSetProvider) and (Components[I].Tag = 100) then
(Components[I] as TDataSetProvider).BeforeUpdateRecord := PubBeforeUpdateRecord;
end;
end;
{ 根據條件返回指定列字段數據 BES96261 }
procedure THPMRP.GetRecStrs(const UserID, Corp_No, TabName, ColName,
ExprStr: WideString; out RstStrs: OleVariant);
var sSQL, sExpr: String;
I: Integer;
begin
sExpr := ExprStr;
If Trim(sExpr) <> '' then sExpr := ' where '+sExpr;
sSQL := Format('select %s from %s'+sExpr,[ColName,TabName,ExprStr]);
with get_Q_RecStrs do
begin
Close;
SQL.Clear;
SQL.Add(StringReplace(ReplaceSQLSafe(sSQL),',',GetUnChar,[rfReplaceAll]));
Open;
RstStrs := VarArrayCreate([0,NegToZero(RecordCount-1)],VarOleStr);
I := 0;
First;
while not Eof do
begin
RstStrs[I] := Fields[0].AsString;
Inc(I);
Next;
end;
Close;
end;
end;
{ 根據用戶及條件提取相關需求數據 BES96261
UserID: 用戶編碼
dstNm: 需求數據集名稱
Corp_No: 公司編碼
Cust_No 客戶編碼(提取指定客戶的數據)
ParamStr: 條件值的集合,使用 '@' 作分隔符
sExpr: 前臺傳來的附帶查詢條件的SQL語句 }
function THPMRP.GetData(const UserID, dstNm, Corp_No, Cust_No: WideString;
ParamStr: OleVariant; const sExpr: WideString): OleVariant;
begin
Try
TmpCDS.Close;
TmpCDS.CommandText := GetSQL(UserID,dstNm,Corp_No,Cust_No,sExpr,ParamStr);
TmpCDS.Open;
Result := TmpCDS.Data;
Finally
TmpCDS.Close;
End;
end;
{ 根據用戶和請求的數據及條件返回取值SQL語句 BES96261 }
Function THPMRP.GetSQL(UserID, dstNm, Corp_No, Cust_No, swhExpr: WideString; ParamStr: OleVariant): WideString;
var sSQL, sExpr, sCrpExpr, sCstExpr: String;
I: Integer;
{ sSQL: 最終組合的SQL語句
sExpr: 數據庫表中的指定條件,通常爲主從連接
sCrpExpr: 提取指定公司的數據條件
sCstExpr: 提取指定客戶的數據條件
}
begin
If Trim(UserID) = '' then UserID := U_PublicFun.Pubchar;
//臨時賦值 { ------------------------ }
UserID := 'SUPER';
sSQL := Format('select * from Sys_GetData where UserID=%s and FrmNm=%s',
[Quotedstr(UserID),Quotedstr(dstNm)]);
with get_Q_RecStrs do
begin
Close;
SQL.Clear;
SQL.Add(ReplaceSQLSafe(sSQL));
Open;
sSQL := '';
If RecordCount <> 0 then
begin
If (not VarIsArray(ParamStr)) or (VarArrayHighBound(ParamStr,1) < 0) then sExpr := ''
else sExpr := FieldByName('Expr').AsString;
{ 根據條件初始化SQL語句 將條件中的參數變量具體化 }
I := 0;
while Pos('@',sExpr)<>0 do
begin
if VarIsArray(ParamStr) and (VarArrayHighBound(ParamStr,1)>= I) then
sExpr := StringReplace(sExpr,'@',ParamStr[I],[rfIgnoreCase])
else sExpr := StringReplace(sExpr,'@',QuotedStr('0'),[rfIgnoreCase]);
Inc(I);
end;
{ 客戶權限 }
sCstExpr := FieldByName('CstExpr').AsString;
If Trim(sCstExpr) <> '' then
sCstExpr := StringReplace(sCstExpr,'@Cust_No',QuotedStr(Cust_No),[rfIgnoreCase])
else
sCstExpr := '';
//公司權限
sCrpExpr := FieldByName('CrpExpr').AsString;
If Trim(sCrpExpr) <> '' then
sCrpExpr := StringReplace(sCstExpr,'@Corp_No',QuotedStr(Corp_No),[rfIgnoreCase])
else
sCrpExpr := '';
//處理附帶的SQL條件表達式
If Trim(swhExpr) <> '' then
begin
If (UpperCase(LeftStr(Trim(swhExpr),2)) <> 'OR') and (UpperCase(LeftStr(Trim(swhExpr),3)) <> 'AND') then
begin
If Trim(sExpr+sCstExpr+sCrpExpr)<>'' then swhExpr := ' And '+swhExpr
else swhExpr := ' where '+swhExpr;
end else
begin
If Trim(sExpr+sCstExpr+sCrpExpr) ='' then swhExpr := ' where 1=1 '+swhExpr;
end;
end;
{ 生成SQL語句 }
sSQL := 'Select '+FieldByName('MaxRec').AsString+' '+FieldByName('ColNm').AsString+
' '+FieldByName('TabNm').AsString+
' '+sExpr+' '+sCrpExpr+' '+ sCstExpr+' '+swhExpr +
' '+FieldByName('OrdSQL').AsString;
end;
Close;
end;
Result := sSQL;
end;
{ 校驗字段是否爲空 BES96261 }
Function THPMRP.CannotNull(FieldStr: String; DeltaDS:TCustomClientDataSet; UpdKind: String=''):String;
var I:Integer;
FieldNm, VisField:String; //Field Name
begin
Result := '';
If UpdKind = 'Del' then Exit;
If Trim(FieldStr)='' then Exit;
While Trim(FieldStr)<>'' do
begin
I:=Pos(';',FieldStr);
If I<=0 then
begin
FieldNm := FieldStr;
FieldStr := '';
end else
begin
FieldNm := Copy(FieldStr,1,I-1);
FieldStr := Copy(FieldStr,I+1,Length(FieldStr)-I);
End;
VisField := Copy(FieldNm,Pos(',',FieldNm)+1,length(FieldNm)-Pos(',',FieldNm));
FieldNm := Trim(Copy(FieldNm,1,Pos(',',FieldNm)-1));
If (VarIsEmpty(DeltaDS.FieldByName(FieldNm).NewValue) or (VarToStr(DeltaDS.FieldByName(FieldNm).NewValue) = ''))
and ((UpdKind='Ins') or ((UpdKind='Upd') and VarIsEmpty(DeltaDS.FieldByName(FieldNm).OldValue))) then
begin
Result := 'Please input '+quotedstr(VisField)+' value.';
Exit;
End;
End;
end;
{ 使用存儲過程更新數據集時賦相應參數值 BES96261
spName: 需調用的更新存儲過程名
DeltaDS: 需更新的數據集
ParmaeStr: 存儲過程參數名及對應的取值字段名
ParameSet: 存儲過程參數名及對應的取(Oldvalue)值字段名,用於關鍵字
UpdKind: 數據更新類型 --修改,新增, 刪除 }
Function THPMRP.SetspParam(spName:String; DeltaDS:TCustomClientDataSet;
ParameStr,ParamSet:WideString; UpdKind: String=''): WideString;
var I: Integer;
S, ParamName,FieldName: String;
begin
If Trim(ParameStr) = '' then Exit;
{ 獲取存儲過程名及相關參數 }
sp_pub_ref.ProcedureName := spName;
sp_pub_ref.Parameters.Refresh;
{ 根據參數名賦需更新數據集對應字段值 }
While Trim(ParameStr) <> '' do
begin
I := Pos(';',ParameStr);
If I <= 0 then
begin
S := ParameStr;
ParameStr := '';
end else
begin
S := Copy(ParameStr,1,I-1);
ParameStr := Copy(ParameStr,I+1,Length(ParameStr)-I);
End;
ParamName := Trim(Copy(S,1,Pos(',',S)-1));
FieldName := Trim(Copy(S,Pos(',',S)+1,length(S)-Pos(',',S)));
if FieldName = '-' then FieldName := Trim(copy(ParamName,2,length(ParamName)-1));
if (VarIsEmpty(DeltaDS.FieldByName(FieldName).NewValue) and (UpdKind<>'Ins')) or (UpdKind='Del') then
sp_pub_ref.Parameters.ParamByName(ParamName).Value := DeltaDS.FieldByName(FieldName).OldValue
else
sp_pub_ref.Parameters.ParamByName(ParamName).Value := DeltaDS.FieldByName(FieldName).NewValue;
End; //end while
{ 賦數據更新類型值 }
if Trim(UpdKind) <> '' then
sp_pub_ref.Parameters.ParamByName('@UpdateKind').Value := UpdKind;
{ 根據關鍵字參數名賦所對應Old值 }
While Trim(ParamSet) <> '' do
begin
I := Pos(';',ParamSet);
If I <= 0 then
begin
S := ParamSet;
ParamSet := '';
end else
begin
S := Copy(ParamSet,1,I-1);
ParameStr := Copy(ParamSet,I+1,Length(ParamSet)-I);
End;
ParamName := Trim(Copy(S,1,Pos(',',S)-1));
FieldName := Trim(Copy(S,Pos(',',S)+1,length(S)-Pos(',',S)));
if FieldName = '-' then FieldName := Trim(copy(ParamName,2,length(ParamName)-1));
sp_pub_ref.Parameters.ParamByName(ParamName).Value := DeltaDS.FieldByName(FieldName).OldValue
End; //end while
sp_pub_ref.ExecProc;
Result := sp_pub_ref.Parameters.ParamByName('@rststr').Value;
end;
{ 根據數據集更新狀態返加對應的字符串 BES96261 }
Function THPMRP.UpdKindStr(var Kind: TUpdateKind): String;
begin
if Kind = ukModify then Result := 'Upd';
if Kind = ukInsert then Result := 'Ins';
if Kind = ukDelete then Result := 'Del';
end;
{ 數據公用更新過程 BES96261 2003-12-25 17:02 }
procedure THPMRP.PubBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet;
UpdateKind: TUpdateKind; var Applied: Boolean);
var sMsg, spName: String;
ChkNull, ParameStr, ParamSet:WideString;
UpdKind: ShortString;
begin
spName := app_spName;
ParameStr := app_ParameStr;
ParamSet := app_ParamSet;
ChkNull := app_ChkNull;
sMsg := '';
UpdKind := UpdKindStr(UpdateKind);
{ 不爲空檢測 }
sMsg := CannotNull(ChkNull, DeltaDS, UpdKind);
if Trim(sMsg) <> '' then //
raise Exception.Create(IntToStr(DeltaDS.RecNo) + Unchar + UpdKind + Unchar + sMsg);
{ 數據更新 }
If Trim(sMsg) = '' then
begin
sMsg := SetspParam(spName,DeltaDS,ParameStr,ParamSet,UpdKind);
if Trim(sMsg) <> '' then //
raise Exception.Create(IntToStr(DeltaDS.RecNo) + Unchar + UpdKind + Unchar + sMsg);
end;
Applied := True;
end;
{ 數據公用提交過程 BES96261
UserID: 用戶編碼,用以權限判斷
dstNm: 提交的功能數據集
Parmastr: 更新參數
vData: 需更新的數據集
Result: 更新過程中需返回的列表 }
function THPMRP.SetData(const UserID, dstNm, ParamStr: WideString;
vData: OleVariant): OleVariant;
var ErrCount: Integer;
begin
If GetAuth(UserID,dstNm,'Apply') = 1000 then
begin
{ 此次更新與上次更新數據集不相同則從後臺取更新數據參數值 }
If dstNm <> app_dspName then
begin
app_dspName := dstNm;
with sp_get_apply do
begin
Close;
Parameters.ParamByName('@dsp_nm').Value := app_dspName;
ExecProc;
app_spName := Parameters.ParamByName('@spName').Value;
app_ParameStr := Parameters.ParamByName('@Pstr1').Value+Parameters.ParamByName('@Pstr2').Value;
app_ParamSet := Parameters.ParamByName('@Pstr3').Value;
app_ChkNull := Parameters.ParamByName('@Chkstr').Value;
end;
end;
Result := tmpdsp.ApplyUpdates(vData,-1,ErrCount);
end;
end;
{ 操作數據集時權限判斷 BES96261 }
function THPMRP.GetAuth(const UserID, dstNm, GrpTyp: WideString): OleVariant;
begin
Result := 1000;
end;
{ 使用存儲過程查詢,並返回結果值 BES96261 }
function THPMRP.GetspData(const UserID, dstNm: WideString;
ParamStr: OleVariant): OleVariant;
begin
FrmServer.Memo1.Lines.Add(UserID + '---' + dstNm);
{ Open Query and Result Data}
If SetspParameters(UserID, dstNm, ParamStr, sp_get_Data) then
begin
sp_get_Data.Open;
Result := dsp_get_spQuery.Data;
sp_get_Data.Close;
end;
end;
{ 執行存儲過程,無結果集返回 }
function THPMRP.ExecProc(const UserID, Corp_No, dstNm: WideString;
ParamStr: OleVariant): Shortint;
begin
Result := -1;
FrmServer.Memo1.Lines.Add(UserID + '---Exec Procedure---' + dstNm);
{ Exec Procedure }
If SetspParameters(UserID, dstNm, ParamStr, sp_exec) then
begin
sp_exec.ExecProc;
Result := 1;
end;
end;
{ 執行存儲過程或通過存儲過程查詢數據時設置存儲過程參數 BES96261 }
Function THPMRP.SetspParameters(UserID, dstNm: String; ParamStr: OleVariant; run_sp_Nm: TADOStoredProc): Boolean;
var spNm: String; //存儲過程名稱
I: Integer;
begin
Result := False;
If Trim(dstNm) = '' then Exit;
If GetAuth(UserID,dstNm,'Query') <> 1000 then Exit;
with sp_get_spNm do
begin
Close;
Parameters.ParamByName('@UserID').Value := UserID;
Parameters.ParamByName('@dstnm').Value := dstNm;
ExecProc;
spNm := Parameters.ParamByName('@spNm').Value;
end;
If Trim(spNm) = '' then Exit;
{ Exec Proc }
run_sp_Nm.Close;
run_sp_Nm.ProcedureName := spNm;
run_sp_Nm.Parameters.Refresh;
If not varIsNull(ParamStr) and VarIsArray(ParamStr) then
begin
For I:=0 to VarArrayHighBound(ParamStr,1) do
begin
case varTypeCntInt(run_sp_Nm.Parameters[I+1].DataType) of
2: run_sp_Nm.Parameters[I+1].Value := StrToFloat(ParamStr[I]);
3: run_sp_Nm.Parameters[I+1].Value := VarCntbool(ParamStr[I]);
else run_sp_Nm.Parameters[I+1].Value := ParamStr[I];
end;
FrmServer.Memo1.Lines.Add(ParamStr[I]);
end; //end for
end;
Result := True;
end;
{ 判數參數類型 }
Function THPMRP.varTypeCntInt(varType: TDataType): Integer;
begin
Case varType of
ftString, ftDate, ftTime, ftDateTime, ftWideString,ftFixedChar :
Result := 1;
ftSmallint, ftInteger, ftWord, ftFloat, ftCurrency, ftBCD, ftLargeint,
ftBytes, ftVarBytes :
Result := 2;
ftBoolean : Result := 3;
else
Result := 1;
end;
end;
{ 根據條件返回指定列字段數據 BES96261 }
procedure THPMRP.GetColStrs(const UserID, Corp_No, TabName, ColName,
ExprStr: WideString; out RstStrs: OleVariant);
var sSQL, sExpr: String;
I: Integer;
begin
sExpr := ExprStr;
If Trim(sExpr) <> '' then sExpr := ' where '+sExpr;
sSQL := Format('select %s from %s'+sExpr,[ColName,TabName,ExprStr]);
with get_Q_RecStrs do
begin
Close;
SQL.Clear;
SQL.Add(sSQL);
Open;
RstStrs := VarArrayCreate([0,NegToZero(Fields.Count-1)],VarOleStr);
If RecordCount > 0 then
begin
For I := 0 to Fields.Count - 1 do
RstStrs[I] := Fields[I].AsString;
end;
Close;
end;
end;
initialization
TComponentFactory.Create(ComServer, THPMRP,
Class_HPMRP, ciMultiInstance, tmFree);
end.
/////***********************************************************///
////U_RDM.dfm文件
object HPMRP: THPMRP
OldCreateOrder = False
OnCreate = RemoteDataModuleCreate
Left = 196
Top = 124
Height = 203
Width = 481
object sp_Pub_Ref: TADOStoredProc
Connection = BesConnection
Parameters = <>
Left = 32
Top = 80
end
object get_Q_RecStrs: TADOQuery
Connection = BesConnection
Parameters = <>
Left = 112
Top = 16
end
object BesConnection: TADOConnection
ConnectionTimeout = 5
LoginPrompt = False
Provider = 'SQLOLEDB.1'
Left = 32
Top = 16
end
object TmpCDS: TClientDataSet
Aggregates = <>
Params = <>
ProviderName = 'tmpdsp'
Left = 192
Top = 16
end
object tmpdsp: TDataSetProvider
Tag = 100
DataSet = Q_tmp
Options = [poAllowCommandText]
UpdateMode = upWhereKeyOnly
Left = 240
Top = 16
end
object Q_tmp: TADOQuery
Connection = BesConnection
CursorType = ctStatic
Parameters = <>
SQL.Strings = (
'')
Left = 288
Top = 16
end
object sp_get_apply: TADOStoredProc
Connection = BesConnection
ProcedureName = 'Bes_S_GetApplyParame;1'
Parameters = <
item
Name = '@RETURN_VALUE'
DataType = ftInteger
Direction = pdReturnValue
Precision = 10
Value = Null
end
item
Name = '@dsp_nm'
Attributes = [paNullable]
DataType = ftString
Size = 50
Value = Null
end
item
Name = '@spName'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 50
Value = Null
end
item
Name = '@Pstr1'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 255
Value = Null
end
item
Name = '@Pstr2'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 255
Value = Null
end
item
Name = '@Pstr3'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 255
Value = Null
end
item
Name = '@Chkstr'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 255
Value = Null
end>
Prepared = True
Left = 386
Top = 16
end
object sp_get_spNm: TADOStoredProc
Connection = BesConnection
ProcedureName = 'Bes_S_GetspQuery;1'
Parameters = <
item
Name = '@RETURN_VALUE'
DataType = ftInteger
Direction = pdReturnValue
Precision = 10
Value = Null
end
item
Name = '@UserID'
Attributes = [paNullable]
DataType = ftString
Size = 50
Value = Null
end
item
Name = '@dstnm'
Attributes = [paNullable]
DataType = ftString
Size = 50
Value = Null
end
item
Name = '@spNm'
Attributes = [paNullable]
DataType = ftString
Direction = pdInputOutput
Size = 50
Value = Null
end>
Left = 386
Top = 72
end
object dsp_get_spQuery: TDataSetProvider
DataSet = sp_get_Data
Left = 385
Top = 126
end
object sp_get_Data: TADOStoredProc
Connection = BesConnection
CommandTimeout = 800
Parameters = <>
Left = 120
Top = 80
end
object sp_exec: TADOStoredProc
Connection = BesConnection
CommandTimeout = 500
Parameters = <>
Left = 192
Top = 80
end
end
/////***********************************************************///
/////公用單元文件 U_PublicFun.pas
unit U_PublicFun;
interface
uses SysUtils, IniFiles, Forms;
Function EncrypKey(Src:String; Key:String='wtgvkssqyouvkxnn2'):string;
Function UncrypKey(Src:String; Key:String='wtgvkssqyouvkxnn2'):string;
Function GetServerConnetionStr: String; //獲取數據庫接字符串
Function UnionStr(const Str1,Str2: String):String;
Function ReplaceSQLSafe(var SQLStr: String): String;
Function GetUnChar: String; //在表達式中替換連接符 值固定爲:'+"'+unchar+'"+'
Function NegToZero(value: Integer): Integer; //如果是負值,則轉爲0
Function VarCntbool(value: Integer): Boolean; overload;
Function VarCntbool(value: string): Boolean; overload;
const
Unchar = ' -- '; //多字段之間的連接分隔符
Pubchar = 'SUPER'; //公用數據編碼 或 用戶編碼
implementation
Function EncrypKey (Src:String; Key:String):string;
var
KeyLen, KeyPos, offset, SrcPos, SrcAsc, Range :Integer;
dest :string;
begin
KeyLen:=Length(Key);
if KeyLen = 0 then key:='wtgvkssqyouvkxnn2';
KeyPos:=0;
Range:=256;
Randomize;
offset:=Random(Range);
dest:=format('%1.2x',[offset]);
for SrcPos := 1 to Length(Src) do
begin
SrcAsc:=(Ord(Src[SrcPos]) + offset) MOD 255;
if KeyPos < KeyLen then KeyPos:= KeyPos + 1 else KeyPos:=1;
SrcAsc:= SrcAsc xor Ord(Key[KeyPos]);
dest:=dest + format('%1.2x',[SrcAsc]);
offset:=SrcAsc;
end;
Result:=Dest;
end;
Function UncrypKey (Src:String; Key:String):string;
var
KeyLen, KeyPos, offset, SrcPos, SrcAsc, TmpSrcAsc :Integer;
dest :string;
begin
KeyLen:=Length(Key);
if KeyLen = 0 then key:='wtgvkssqyouvkxnn2';
KeyPos:=0;
offset:=StrToInt('$'+ copy(src,1,2));
SrcPos:=3;
repeat
try
SrcAsc:=StrToInt('$'+ copy(src,SrcPos,2));
if KeyPos < KeyLen Then KeyPos := KeyPos + 1
else KeyPos := 1;
TmpSrcAsc := SrcAsc xor Ord(Key[KeyPos]);
if TmpSrcAsc <= offset then TmpSrcAsc := 255 + TmpSrcAsc - offset
else TmpSrcAsc := TmpSrcAsc - offset;
dest := dest + chr(TmpSrcAsc);
offset:=srcAsc;
SrcPos:=SrcPos + 2;
except
end;
until SrcPos >= Length(Src);
Result:=Dest;
end;
{ 獲取數據庫接字符串 BES96261 2003-11-18 18:50 }
Function GetServerConnetionStr: String;
var tempIni: TIniFile;
begin
tempIni := TIniFile.Create(ExtractFilePath(Application.ExeName)+'ServerConfig.ini');
Try
Result := 'Provider=SQLOLEDB.1;Password='+UncrypKey(tempIni.ReadString('SYSTEM', 'PassWord', ''))+
';Persist Security Info=True;User ID='+UncrypKey(tempIni.ReadString('SYSTEM', 'UserID', ''))+
';Initial Catalog='+tempIni.ReadString('SYSTEM', 'DBNAME', '')+
';Data Source='+tempIni.ReadString('SYSTEM', 'SERVER', '')
Finally
tempIni.Free;
End;
end;
{ 連接字符串,當Str2爲空時返回空串 BES96261 2003-11-23 22:10 }
Function UnionStr(const Str1,Str2: String):String;
begin
If Length(Str2) = 0 then
Result := ''
else
Result := Str1 + ' ' + Str2;
end;
{ 過濾從客戶端傳來SQL參數中的不安全關鍵字 BES96261 2003-11-23 10:15 }
Function ReplaceSQLSafe(var SQLStr: String): String;
var S: String;
begin
S := StringReplace(SQLStr,'--','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'/*','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Delete ','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Drop ','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Exec ','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Create ','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Alter ','',[rfReplaceAll, rfIgnoreCase]);
S := StringReplace(S,'Update ','',[rfReplaceAll, rfIgnoreCase]);
Result := S;
end;
{ 在表達式中替換連接符 BES96261 2003-12-09 23:21 }
Function GetUnChar: String;
begin
Result := '+'+QuotedStr(Unchar)+'+';
end;
{ 若數值爲負,則轉爲0輸出 BES96261 2003-12-09 23:07 }
Function NegToZero(Value: Integer): Integer;
begin
If Value < 0 then Result := 0
else Result := Value
end;
Function VarCntbool(value: Integer): Boolean;
begin
Result := (value <> 0);
end;
Function VarCntbool(value: string): Boolean;
begin
If (Trim(value)='') or (Trim(value)='0') then
Result := False
else
Result := True;
end;
end.
Delphi之MIDAS三層完美解決方案----中間層構建
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.