所谓的“真3层”有时候是需要客户端上传数据集的TPARAMS到中间件的。
现在,高版本的DATASNAP的远程方法其实也是直接可以传输TPARAMS类型的变量,但是DELPHI7(七爷)、六爷它们是不支持的。
高版本的DATASNAP要让六爷、七爷它们调用,不能直接传TPARAMS,得转换。
procedure VariantToParams(input: OleVariant; par: TParams);
var n, i: integer;begin try n := 0; i := 0; par.Clear; while VarArrayHighBound(input, 1) >= (n + 5) do begin par.CreateParam(TFieldType(input[n + 1]), input[n + 2], TParamType(input[n + 4])); par.Items[i].Value := input[n + 3]; par.Items[i].Size := input[n + 5]; n := n + 5; i := i + 1; end; except Exit; end;end;function ParamsToVariant(par: TParams): OleVariant;
var n, i: integer;begin try Result := VarArrayCreate([1, par.Count * 5], VarVariant); n := 0; i := 0; while par.Count > i do begin Result[n + 1] := Ord(par.Items[i].DataType); Result[n + 2] := par.Items[i].Name; Result[n + 3] := par.Items[i].Value; Result[n + 4] := ord(par.Items[i].ParamType); Result[n + 5] := par.Items[i].Size; i := i + 1; n := n + 4; end; result := Result; except Exit; end;end;其实,PARAMS和OLEVARIANT相互转换的函数,DELPHI已经现成提供了:
DBCLITNT.PAS
function PackageParams(Params: TParams; Types: TParamTypes = AllParamTypes): OleVariant;
var I, Idx, Count: Integer;begin Result := NULL; Count := 0; for I := 0 to Params.Count - 1 do if Params[I].ParamType in Types then Inc(Count); if Count > 0 then begin Idx := 0; Result := VarArrayCreate([0, Count - 1], varVariant); for I := 0 to Params.Count - 1 do with Params[I] do if ParamType in Types then begin if VarIsCustom(Value) then Result[Idx] := VarArrayOf([Name, VarToStr(Value), Ord(DataType), Ord(ParamType), Size, Precision, NumericScale]) else Result[Idx] := VarArrayOf([Name, Value, Ord(DataType), Ord(ParamType), Size, Precision, NumericScale]); Inc(Idx); end; end;end;procedure UnpackParams(const Source: OleVariant; Dest: TParams);
var TempParams: TParams; HighBound, i: Integer;begin if not VarIsNull(Source) and VarIsArray(Source) and VarIsArray(Source[0]) then begin TempParams := TParams.Create; try for i := 0 to VarArrayHighBound(Source, 1) do begin HighBound := VarArrayHighBound(Source[i], 1); with TParam(TempParams.Add) do begin Name := Source[i][0]; if HighBound > 1 then DataType := TFieldType(Source[i][2]); if HighBound > 2 then ParamType := TParamType(Source[i][3]); if HighBound > 3 then Size := Source[i][4]; if HighBound > 4 then Precision := Source[i][5]; if HighBound > 5 then NumericScale := Source[i][6]; Value := Source[i][1]; // Value must be set last end; end; Dest.Assign(TempParams); finally TempParams.Free; end; end;end;