从ADO调用Oracle SP

时间:2018-12-21 07:11:48

标签: oracle delphi ado

我正在尝试使用ADO中的in和out参数调用存储过程

首先是一个小包装和一个SP:

CREATE OR REPLACE PACKAGE CD_package IS
   TYPE CD_cursor IS REF CURSOR;
   PROCEDURE CDList ( pCost IN Number, pList OUT CD_Cursor ) ;
END CD_package;
/
CREATE OR REPLACE PACKAGE BODY CD_package AS
PROCEDURE CDList ( pCost IN Number, pList OUT CD_Cursor ) IS
-- returns a list of titles available at cost pCost
BEGIN
   OPEN pList FOR
    SELECT CURRENT_TIMESTAMP FROM DUAL;

END CDList;

END CD_package;

还有我的Delphi代码:

      With SP do
      begin
        Close;
        Connection := ADOConnection1;
  ProcedureName := 'CD_package.CDList';  
        Parameters.Clear;
        Parameters.CreateParameter('pCost', ftFloat, pdInput, 0, 2.2);
        Open;
        Last;
      end; // with

SP我是TADOStoredProc,而ADOConnection1是到我的OracleDatabase的有效连接。

根据隔离站点,您不应该创建OUT过程。但在这里我最终陷入了困境22。

如果我省略该参数,则会出现关于缺少参数的错误:enter image description here

如果我添加一个Cursor参数

...
    Parameters.CreateParameter('pList', ftCursor, pdOutput, -1, NULL);
...

我收到一个错误消息,指出参数未正确声明 enter image description here

显然可以与ADO隔离开来,但这是不可能的,因为程序ID充满了对_RecordSet的引用

因此,简而言之,如何使用ADO在Oracle中调用SP?

唯一固定的东西是Delphi和ADO。您可以随意将TADOStoredProc更改为TADOCommand或查询。只要它正在工作。

1 个答案:

答案 0 :(得分:0)

我使用ODAC找到了“解决方案”:

绝不是最佳选择。但是,由于我无法摆脱ADO驱动程序,因此到目前为止,这是我的解决方案:

uses
  System.Win.ComObj;

type
  TCustomADODataSetHelper = class helper for TCustomADODataSet
  public
    procedure AssignFrom(Source: TMemDataSet);
  end;

  { TCustomADODataSetHelper }

procedure TCustomADODataSetHelper.AssignFrom(Source: TMemDataSet);
var
  RS: Variant;
  Stream: TStringStream;
begin
  Stream := TStringStream.Create;
  try
    Source.SaveToXML(Stream);
    Stream.Position := 0;
    RS := CreateOleObject('ADODB.Recordset');
    RS.Open(TStreamAdapter.Create(Stream) as IUnknown);
    Recordset := IUnknown(RS) as _Recordset;
  finally
    Stream.Free;
  end;
end;

procedure TForm8.FormCreate(Sender: TObject);
begin
  with OraStoredProc1 do
  begin
    StoredProcName := 'DDK.GetSystemSettings';;
    Params.CreateParam(ftString, 'APrefix', TParamType.ptInput).Value := '';
    Params.CreateParam(ftCursor, 'ASettings', TParamType.ptOutput);
    Open;
  end;

  ADOStoredProc1.AssignFrom(OraStoredProc1);
  DataSource1.Dataset := ADOStoredProc1;
end;