第一关我对德尔福仍然有点绿色,所以这可能是一个“平凡的细节”,正在被看过。 [提前抱歉]
我需要从包中包含的Oracle 11g游标创建TSQLDataset或TClientDataSet。我使用Delphi XE2和DBExpress连接到DB和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;
我在SQL Developer中执行此过程没有问题,问题出在DataSnap服务器上的此代码中:
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分配param值而没有任何运气。 如果它更容易或产生结果,我不会被认为从函数返回TDataSet。数据用于填充自定义对象属性。
答案 0 :(得分:3)
正如this answer
中提到的paulsm4,Delphi并不关心获取存储过程参数描述符,因此您必须自己完成。要从包中获取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;
答案 1 :(得分:2)
我认为Delphi不会自动识别Oracle参数名称并为您填写。我想你需要添加参数。例如:
with strProc.Params.Add do
begin
Name := 'abbr';
ParamType := ptInput;
Value := ZZZTOP';
...
end;