在三層開發中我們不能直接把sql語句寫在客戶端,雖然軟件最終是通過sql和數據庫打交道的,這個時候我們該怎麼辦呢,我們可以通過 客戶端傳遞參數,服務端插件解析參數的方式來解決這個問題,這樣還可以避免類似sql注入的漏洞,好了,不多說,本文重點是序列還原 TFDParams
在ClientDatset的時候 我們可以序列化Tparams 爲OleVariant (在DBClient單元 UnpackParams /PackageParams)
我在Firedac中還未找到序列化TFDParams的方法,所以自己就模仿PackageParams 寫了 TFDParams 和流轉和的函數。
(如果哪位高手知道系統有自帶的函數,高手我一下哈)
/// <summary>
/// 參數序列化流
/// </summary>
/// <param name="aParams"></param>
/// <returns>TStream</returns>
function TForm1.ParamsToStream(aParams: TFDParams): TStream;
var
QMP: TQMsgPack;
I, Idx, Count: Integer;
begin
QMP := TQMsgPack.Create;
Result := TMemoryStream.Create;
try
Count := 0;
for I := 0 to aParams.Count - 1 do
if aParams[I].ParamType in AllParamTypes then
Inc(Count);
if Count > 0 then
begin
Idx := 0;
for I := 0 to aParams.Count - 1 do
if aParams[I].ParamType in AllParamTypes then
begin
QMP.ForcePath(idx.ToString).ForcePath('Name').AsString := aParams[I].Name;
QMP.ForcePath(idx.ToString).ForcePath('Value').AsVariant := aParams[I].Value;
QMP.ForcePath(idx.ToString).ForcePath('DataType').AsInteger := Ord(aParams[I].DataType);
QMP.ForcePath(idx.ToString).ForcePath('ParamType').AsInteger := Ord(aParams[I].ParamType);
QMP.ForcePath(idx.ToString).ForcePath('Size').AsInteger := aParams[I].Size;
QMP.ForcePath(idx.ToString).ForcePath('Precision').AsInteger := aParams[I].Precision;
QMP.ForcePath(idx.ToString).ForcePath('NumericScale').AsInteger := aParams[I].NumericScale;
Inc(Idx);
end;
end;
QMP.SaveToStream(Result);
finally
QMP.Free;
end;
end;
/// <summary>
/// 流還原成 TFDParams
/// </summary>
/// <param name="Stream"></param>
/// <returns>TFDParams</returns>
function TForm1.StreamTOParams(Stream: TStream): TFDParams;
var
QMP: TQMsgPack;
LParam: TFDParam;
I: Integer;
begin
QMP := TQMsgPack.Create;
Result := TFDParams.Create;
try
Stream.Position := 0;
QMP.LoadFromStream(Stream);
for I := 0 to QMP.Count - 1 do
begin
LParam := TFDParam(Result.Add);
LParam.Name := QMP.ForcePath(i.ToString).ForcePath('Name').AsString;
LParam.DataType := TFieldType(QMP.ForcePath(i.ToString).ForcePath('DataType').AsInteger);
LParam.ParamType := TParamType(QMP.ForcePath(i.ToString).ForcePath('ParamType').AsInteger);
LParam.Size := QMP.ForcePath(i.ToString).ForcePath('Size').AsInteger;
LParam.Precision := QMP.ForcePath(i.ToString).ForcePath('Precision').AsInteger;
LParam.NumericScale := QMP.ForcePath(i.ToString).ForcePath('NumericScale').AsInteger;
LParam.Value := QMP.ForcePath(i.ToString).ForcePath('Value').AsVariant;
end;
finally
QMP.Free;
end;
end;
調用:
TMS := ParamsToStream(FDQuery1.Params);//序列化參數
FDQuery1.Params.Clear;
TMS.Position := 0;
FDQuery1.Params.Assign(StreamToParams(TMS));//還原參數
全部源碼 我已經上傳到 :
http://download.csdn.net/detail/u013051638/9717314
Q羣 Delphi Home 235236282,歡迎delphi 愛好者加入,一起學習、進步。