2012-10-24 29 views
1

第一次關閉我對Delphi仍然有點綠色,所以這可能是一個「世俗的細節」,它已經被忽略了。 [提前抱歉]如何使用Delphi和DBExpress將Oracle遊標從存儲過程作爲客戶端數據集返回

我需要從軟件包中包含的Oracle 11g光標創建TSQLDataset或TClientDataSet。我使用Delphi XE2和DBExpress連接到數據庫和DataSnap以將數據發送回客戶端。

我在執行Delphi代碼中的存儲過程時遇到問題。

套餐頭

create or replace 
PACKAGE KP_DATASNAPTEST AS 
    procedure GetFaxData(abbr varchar2, Res out SYS_REFCURSOR); 
END KP_DATASNAPTEST; 

包體

create or replace 
PACKAGE body KP_DATASNAPTEST AS 
    procedure GetFaxData(abbr varchar2, Res out SYS_REFCURSOR)is 
    Begin 
    open Res for 
     SELECT Name, 
       Address1, 
       City, 
       fax_nbr 
     FROM name 
     JOIN phone on name.Abrv = phone.abrv 
     WHERE phone.fax_nbr is not null and name.abrv = abbr; 
    end; 
END KP_DATASNAPTEST; 

我有執行的DataSnap服務器上的代碼在SQL Developer中的問題在於這個過程沒有問題:

function TKPSnapMethods.getCDS_Data2(): OleVariant; 
var 
    cds: TClientDataSet;  
    dsp: TDataSetProvider; 
    strProc: TSQLStoredProc;  
begin 
    strProc := TSQLStoredProc.Create(self); 
    try 
    strProc.MaxBlobSize := -1; 
    strProc.SQLConnection:= SQLCon;//TSQLConnection 

    dsp := TDataSetProvider.Create(self); 
    try 
     dsp.ResolveToDataSet := True; 
     dsp.Exported := False; 
     dsp.DataSet := strProc; 
     cds := TClientDataSet.Create(self); 
     try 
     cds.DisableStringTrim := True; 
     cds.ReadOnly := True; 
     cds.SetProvider(dsp); 

     strProc.Close; 
     strProc.StoredProcName:= 'KP_DATASNAPTEST.GetFaxData'; 
     strProc.ParamCheck:= true; 
     strProc.ParamByName('abbr').AsString:= 'ZZZTOP'; 
     strProc.Open; //<--Error: Parameter 'Abbr' not found. 

     cds.Open; 
     Result := cds.Data; 
     finally 
     FreeAndNil(cds); 
     end; 
    finally 
     FreeAndNil(dsp); 
    end; 
    finally 
    FreeAndNil(strProc); 
    self.SQLCon.Close; 
    end; 
end; 

我也嘗試通過ClientDataSet分配參數值,但沒有任何運氣。 如果它更容易或產生結果,我不會同意從函數返回一個TDataSet。數據用於填充自定義對象屬性。

+0

我能夠在數據模式掉落的部件,使通過該數據庫靜態連接來獲得此功能: '的TClientdataSet .ProviderName-> TDataSetProvider.Dataset-> TSQLStoredProc.SQLConnection - >設爲TSQLConnection TSQLStoredProc.PackageName - > 'KP_DATASNAPTEST' TSQLStoredProc.StoredProcName - > 'GETFAXDATA' TSQLStoredProc.Params.ABBR - >「ZZZTOP'' 數據捕捉功能只是打開ClientDataset,返回Clien tDataSet.Data然後關閉連接。 不知何故,我需要使這更加動態。 –

回答

3

由於paulsm4在this answer提到,德爾福並不關心怎樣存儲過程的參數描述符,所以你自己要它。要獲得從包中的Oracle存儲過程的參數,可以,你可以嘗試使用GetProcedureParams方法來填充參數的描述符列表,並與LoadParamListItems程序與列表Params集合填寫。在代碼中,它可能如下所示。

請注意,下面的代碼根據文檔編寫只是瀏覽器,所以它是未經考驗的。是的,約釋放ProcParams變量,這是由FreeProcParams步驟完成:

var 
    ProcParams: TList; 
    StoredProc: TSQLStoredProc; 
    ... 
begin 
    ... 
    StoredProc.PackageName := 'KP_DATASNAPTEST'; 
    StoredProc.StoredProcName := 'GetFaxData'; 
    ProcParams := TList.Create; 
    try 
    GetProcedureParams('GetFaxData', 'KP_DATASNAPTEST', ProcParams); 
    LoadParamListItems(StoredProc.Params, ProcParams); 
    StoredProc.ParamByName('abbr').AsString := 'ZZZTOP'; 
    StoredProc.Open; 
    finally 
    FreeProcParams(ProcParams); 
    end; 
    ... 
end; 
+0

修復了Parameter not found錯誤。一旦我添加了'StoredProc.PackageName:='KP_DATASNAPTEST'; StoredProc.StoredProcName:='GetFaxData';'建議修復後。當我嘗試在運行時分配所有值時,我現在返回一個空的ClientDataSet。如果我在設計時這樣做,我會得到預期的結果。 –

2

我不認爲德爾福將自動地認識到甲骨文的參數名稱,並填寫他們給你的。我認爲你需要添加參數。例如:

with strProc.Params.Add do 
begin 
    Name := 'abbr'; 
    ParamType := ptInput; 
    Value := ZZZTOP'; 
    ... 
end; 
+1

更安全和進行維修更好是使用['GetProcedureParams'](http://docwiki.embarcadero.com/Libraries/XE3/en/Data.SqlExpr.TSQLConnection.GetProcedureParams)和['LoadParamListItems'](HTTP:/ /docwiki.embarcadero.com/Libraries/XE3/en/Data.SqlExpr.LoadParamListItems)方法。 [無論如何] – TLama

+0

該解決方案還解決了參數未找到問題。一旦我打電話給'StoredProc.PackageName:='KP_DATASNAPTEST'; StoredProc。'params.add'後的StoredProcName:='GetFaxData';''我仍然遇到一個問題,那就是當我在運行時設置所有內容時,我的ClientDataSet是空的。如果我在設計時綁定所有組件,我會得到預期的結果。有任何想法嗎??? –

相關問題