unidac儲存過程

delphi中间件發表於2024-12-07

unidac儲存過程

unit DB.storedproc;
//cxg 2024-8-31
//儲存過程
{$i def.inc}

interface

uses
  //mormot------
  mormot.core.variants,
  //my-------
  db.Unidac,
  sys.global, DB.unidacpool, dataset.Serialize,
  //unidac-------
  uni,
  //system-------
  Classes, SysUtils, DB;

type
  { Tsp }

  Tsp = record
    dbid: string;       //資料庫帳套號
    ctxt: Tcontext;     //通訊上下文
    procName: string;   //儲存過程名
    inParam: Pjson;//入參
    //執行儲存過程
    procedure Open;
    //給input引數賦值
    procedure onInParam(sp: TUniStoredProc; param: Pjson);
    //序列output引數
    procedure onOutParam(sp: TUniStoredProc; var param: Tjson);
  end;

implementation

{ Tsp }

procedure Tsp.Open;
var
  db: tdb;
  pool: tdbpool;
  jo: Tjson;
  i: integer;
begin
  jo.InitObject([]);
  try
    try
      pool := GetDBPool(dbid);
      db := pool.Lock;
      DB.sp.Close;
      DB.sp.Params.Clear;
      DB.sp.StoredProcName := procName;
      DB.sp.active := True;         //自動生成儲存過程的引數
      onInParam(DB.sp, inparam);    //處理入參
      DB.sp.Execute;                //執行儲存過程
      onOutParam(DB.sp, jo);        //處理出參
      i := 0;
      repeat                        //返回多個資料集
        jo.AddValue('dataset' + i.ToString, _json(DB.sp.tojsonarraystring));
        Inc(i);
      until not DB.sp.OpenNext;
      send(ctxt, jo.toJSON);
    except
      on E: Exception do
      begin
        send(ctxt, error(E.Message));
        WriteLog('db.storedproc.open()' + E.Message);
      end;
    end;
  finally
    pool.Unlock(db);
  end;
end;

procedure Tsp.onInParam(sp: TUniStoredProc; param: Pjson);
var
  i: integer;
  p: Tuniparam;
  pname: string;
begin
  try
    for i := 0 to sp.Params.Count - 1 do
    begin
      p := sp.Params[i];
      pname := p.Name;
      if sametext('return_value', pname) then continue;
      if p.ParamType in [ptUnknown, ptOutput, ptResult, ptInputOutput] then continue;
      case p.DataType of
        ftstring, ftwidestring: p.AsWideString := param.s[pname];
        ftLargeint: p.AsLargeInt := param.i[pname];
        ftInteger: p.AsInteger := param.i[pname];
        ftboolean: p.AsBoolean := param.b[pname];
        ftfloat, ftCurrency: p.AsFloat := param.d[pname];
        ftDateTime: p.AsDateTime := param.d[pname];
      end;
    end;
  except
    on E: Exception do
    begin
      send(ctxt, error(E.Message));
      WriteLog('db.storedproc.onInParam()' + E.Message);
    end;
  end;
end;

procedure Tsp.onOutParam(sp: TUniStoredProc; var param: Tjson);
var
  p: Tuniparam;
  i: integer;
  pname: string;
begin
  try
    for i := 0 to sp.Params.Count - 1 do
    begin
      p := sp.Params[i];
      pname := p.Name;
      if sametext(pname, 'return_value') then continue;
      if p.ParamType in [ptUnknown, ptInput, ptResult] then continue;
      case p.DataType of
        ftstring, ftwidestring: param.S[pname] := p.AsWideString;
        ftLargeint: param.I[pname] := p.AsLargeInt;
        ftInteger: param.I[pname] := p.AsInteger;
        ftBoolean: param.B[pname] := p.AsBoolean;
        ftFloat, ftCurrency, ftDateTime: param.D[pname] := p.AsFloat;
      end;
    end;
  except
    on E: Exception do
    begin
      send(ctxt, error(E.Message));
      WriteLog('db.storedproc.onOutParam()' + E.Message);
    end;
  end;
end;

end.

json入參

{
    "procname":"sp_9",
    "inparam":{"goodsid":"100036"}
}

相關文章