1

この質問は、私の前の質問に直接関連しています。

パッケージに含まれているOracle11gカーソルからクライアント上にTClientDataSetを作成する必要があります。Delphi XE2とDBExpressを使用してDBに接続し、DataSnapを使用してデータをクライアントに送り返しています。

設計時にTSQLStoredProcをTClientDatasetに構成すると、カーソルをTClientDatasetとして問題なく返すことができ、期待される結果を得ることができます。

実行時にストアドプロシージャを実行しようとすると、空のTClientDatasetが返されます。

実行時にTSQLStoredProcを使用してOracle11gストアドプロシージャを構成および実行することは可能ですか?

DataSnapサーバー

設計時データモジュールコード[テキストとして表示]

    object StrProc1: TSQLStoredProc
    SchemaName = 'xxxx'
    MaxBlobSize = -1
    Params = <
      item
        DataType = ftWideString
        Precision = 2000
        Name = 'ABBR'
        ParamType = ptInput
        Value = 'ZZZTOP' 
      end
      item
        DataType = ftCursor
        Precision = 8000
        Name = 'RES'
        ParamType = ptOutput
        Size = 8000
      end>
    PackageName = 'KP_DATASNAPTEST'
    SQLConnection = SQLConnection1
    StoredProcName = 'GETFAXDATA'
    Left = 408
    Top = 72
  end
  object DataSetProvider1: TDataSetProvider
    DataSet = StrProc1
    Left = 408
    Top = 120
  end
  object ClientDataSet1: TClientDataSet
    Aggregates = <>
    Params = <>
    ProviderName = 'DataSetProvider1'
    Left = 408
    Top = 176
  end

デザインタイム設定を実行する機能

function TKPSnapMethods.getCDS_Data3: OLEVariant;
begin    
 self.ClientDataSet1.Open;
 result:= self.ClientDataSet1.Data;
 self.SQLConnection1.Close;
end;

ランタイム構成を実行する関数これは、空のClientDataSetを返すコードです。目的は、ピースを接続し、パラメーターの値を設定し、CDSを開いて、CDS.Dataを返すことです。

function TKPSnapMethods.getCDS_Data2(schema: String): OleVariant;
var
  cds: TClientDataSet;
  dsp: TDataSetProvider;
  strProc: TSQLStoredProc;
  ProcParams: TList;
begin
  strProc := TSQLStoredProc.Create(self);
  try
    strProc.SQLConnection:= SQLCon;//<--A TSQLConnection    
    dsp := TDataSetProvider.Create(self);
    try
      dsp.DataSet := strProc;

      cds := TClientDataSet.Create(self);
      try
        cds.DisableStringTrim := True;
        cds.ReadOnly := True;
        cds.SetProvider(dsp);

        ProcParams:= TList.Create;    
        try
          //Load Stored Procedure Parameters
          SQLCon.GetProcedureParams('GETFAXDATA','KP_DATASNAPTEST',Schema,ProcParams);
          LoadParamListItems(StrProc.Params,ProcParams);
          
          strProc.ParamByName('ABBR').AsString := 'ZZZTOP';//<--Assign Parms
          strProc.MaxBlobSize := -1;
          strProc.SchemaName:= Schema;
          strproc.PackageName:='KP_DATASNAPTEST';
          strProc.StoredProcName:= 'GETFAXDATA';
          cds.Open;
          Result := cds.Data;
        finally
          FreeProcParams(ProcParams);
        end;
      finally
        FreeAndNil(cds);
      end;
    finally
      FreeAndNil(dsp);
    end;
  finally
    FreeAndNil(strProc);
    self.SQLCon.Close;
  end;
end;

クライアントコードこれは、DataSnapサーバーへの接続を作成するテストフォームであり、ServerMethodsを実行し、結果を文字列グリッドに表示します。

procedure TForm1.Button1Click(Sender: TObject);
var
 proxy:TKpSnapMethodsClient;
 cds :TClientDataSet;
 field: TField;
 r,c:integer;
begin
  r:=0;
  c:=0;
  SQLConTCPSERV.Connected := True; //TSQLConnection
  proxy:= TKPSnapMethodsClient.Create(SQLConTCPSERV.DBXConnection,false);
  cds:= TClientDataSet.Create(nil);
  try
    //cds.Data:= proxy.getCDS_Data2('TESTTH');//<--Runtime function
    cds.Data:= proxy.getCDS_Data3; //<--Design time function
    if cds <> nil then
    begin
      cds.Open;
      cds.First;
      //String grid to display CDS contents.
      strGrid1.ColCount:= cds.FieldCount; //returns correct #
      strGrid1.RowCount:= cds.RecordCount;

      while not cds.Eof do  //<--runtime wont make it past here
      begin
        for field in cds.fields do //loop fields
        begin
          strgrid1.Cells[c,r]:= field.Text; //display results.
          c:=c+1;
        end;
        c:=0;
        r:=r+1;            
        cds.Next;
      end;
    end
    else showmessage('DataSet is NIL');
  finally
    cds.Free;
    proxy.Free;
    SQLConTCPSERV.Connected := False;
  end;
end;

一度agianになったら、Delphi言語に慣れていないことを告白しなければなりません。私はgoogle、code.google、Embarcadero Developer Network、DBExpressのドキュメントをすべて検索しましたが役に立ちませんでした。設計時間と実行時間に違いがある理由がわかりません。

4

1 に答える 1

1

問題を解決しました。問題は、TSQLStoredProcコンポーネントに値を割り当てる順序にあります。

このコードを呼び出すとき:

strproc.PackageName:='KP_DATASNAPTEST';
strProc.StoredProcName:= 'GETFAXDATA';

パラメータがクリアされます。以下は、Data.SqlExprにあるStoredProcNameを設定するためのコードです。

procedure TSQLStoredProc.SetStoredProcName(Value: UnicodeString);
begin
  //if FStoredProcName <> Value then
  //begin
    FStoredProcName := Value;
    SetCommandText(Value);
    if Assigned(FProcParams) then  // free output params if any
      FreeProcParams(FProcParams);
  //end;
end;

FProcParamsが割り当てられているかどうかを確認できるように、FreeProcParamsはパラメータを解放する呼び出しです。param値を割り当てた後にStroredProcNameを設定していたため、コードはクリアされたparamsで実行され、空のカーソルを返していました。

[getCDS_Data2から]実行時に正しい結果を生成する順序は次のとおりです。

strProc.SchemaName:= Schema;
SQLCon.GetProcedureParams('GETFAXDATA','KP_DATASNAPTEST',Schema,ProcParams);
LoadParamListItems(StrProc.Params,ProcParams);

strproc.PackageName:='KP_DATASNAPTEST';
strProc.StoredProcName:= 'GETFAXDATA';
strProc.MaxBlobSize := -1;
strProc.ParamCheck:=true;

strProc.ParamByName('ABBR').AsString := 'ZZZTOP';

cds.Open;
于 2012-11-02T15:48:31.930 に答える