【问题标题】:Given a recordset, how to populate a TDataSet descendant, in order to populate a grid later?给定一个记录集,如何填充 TDataSet 后代,以便稍后填充网格?
【发布时间】:2014-02-20 16:24:13
【问题描述】:

目前我已按照documentation 中的示例进行操作。

具体例子命名为:

示例:存储过程返回多个行集

这是从上面的例子翻译过来的delphi代码:

//Copied from ADODB.pas
function CreateADOObject(const ClassID: TGUID): IUnknown;
var
  Status: HResult;
  FPUControlWord: Word;
begin
  asm
    FNSTCW  FPUControlWord
  end;
  Status := CoCreateInstance(ClassID, nil, CLSCTX_INPROC_SERVER or
    CLSCTX_LOCAL_SERVER, IUnknown, Result);
  asm
    FNCLEX
    FLDCW FPUControlWord
  end;
  if (Status = REGDB_E_CLASSNOTREG) then
    raise Exception.CreateRes(@SADOCreateError) else
    OleCheck(Status);
end;

var            
  Con: TADOConnection;
  RSet: _Recordset;
  Cmd: _Command;
  P1, P2: _Parameter;
  i: integer;

  RecordsAffected: OleVariant;
begin
  Con := TADOConnection.Create(nil);
  try
    Con.ConnectionString := PromptDataSource(Handle, '');
    Con.Open('user', 'password');

    Cmd := CreateADOObject(CLASS_Command) as _Command;
    try
      Cmd.Set_ActiveConnection(Con.ConnectionObject);

      P1 := Cmd.CreateParameter('P1', adSmallInt, adParamInput, 0, 1);
      Cmd.Parameters.Append(P1);
      P2 := Cmd.CreateParameter('P2', adSmallInt, adParamOutput, 0, EmptyParam);
      Cmd.Parameters.Append(P2);

      Cmd.Properties['PLSQLRSet'].Value := True;
      Cmd.CommandType := adCmdText;
      Cmd.CommandText := '{CALL Employees.GetEmpRecords(?, ?)}';

      RSet:= CreateADOObject(CLASS_Recordset) as _RecordSet;
      try    
        //If I use Execute, the CursorLocation will be adUseServer
        RSet.Open(Cmd, EmptyParam, adUseClient, adOpenStatic, adCmdText);

        ShowMessage(IntToStr(RSet.RecordCount));
        for I:= 0 to RSet.Fields.Count-1 do
        begin
          showmessage(vartostr(RSet.Fields.Item[i].Name)+': '+vartostr(RSet.Fields.Item[i].Value));
        end;

        Cmd.Properties['PLSQLRSet'].Value := False;  
      finally
        RSet := nil;
      end;

    finally
      Cmd := nil;
    end;

  finally
    Con.Free;
  end;
end;

注意:我将程序更改为只返回一个光标!


问题:

1.a) 如何从记录集中填充数据集?

或者

1.b) 还有其他方法可以通过 Delphi 中的 ADO 从 oracle 过程中捕获游标参数吗?


更新 1:

按照 MartynA 的建议,我尝试使用 TADQuery,但到目前为止没有成功:

object ADOQuery1: TADOQuery
    Connection = ADOConnection1
    CursorType = ctStatic
    Parameters = <
      item
        Name = 'param0'
        DataType = ftUnknown
        Direction = pdOutput
        Size = -1
        Value = Null
      end
      item
        Name = 'param1'
        DataType = ftSmallint
        Size = -1
        Value = 7084
      end
      item
        Name = 'param2'
        DataType = ftSmallint
        Direction = pdOutput
        Size = -1
        Value = Null
      end>
    SQL.Strings = (
      '{CALL Employees.GetEmpRecords(:param0, :param1, :param2)}')
    Left = 560
    Top = 96
  end


procedure TForm1.ADOConnection1WillExecute(Connection: TADOConnection;
  var CommandText: WideString; var CursorType: TCursorType;
  var LockType: TADOLockType; var CommandType: TCommandType;
  var ExecuteOptions: TExecuteOptions; var EventStatus: TEventStatus;
  const Command: _Command; const Recordset: _Recordset);
begin
  CommandType := cmdText;
  Command.Properties['PLSQLRSet'].Value := True;
end;

【问题讨论】:

  • 不确定为什么需要使用原始 RecordSet。您不能使用 TAdoQuery 或 TAdoDataSet 检索数据吗?两者都有 NextRecordSet 方法,并且可以使用标准的 DB 感知控件,例如 TDBGrid。
  • 是的,您可以使用 ado 查询调用存储过程
  • @JerryDodge 我正在尝试,但到目前为止没有任何效果
  • @MartynA 正如我在问题中所说,我只需要第一个记录集,而不需要第二个

标签: oracle delphi oledb ado procedure


【解决方案1】:

您可以将记录集直接分配给 ADODataset

ADODataset := TADODataset.Create(nil);
ADODataset.Recordset := RecordsetData;

【讨论】:

  • +1 是的,我在你回答前几分钟就想到了,谢谢你
【解决方案2】:

回答第一个很简单:

    RSet.Open(Cmd, EmptyParam, adUseClient, adOpenStatic, adCmdText);

    DataSet := TADOQuery.Create(nil);
    try
      DataSet.Recordset := RSet;
      ...

当您将 RecordSet 'SET' 到 DataSet 中时,它会自动填充记录集数据。

【讨论】:

  • 这可行,但如果您提供了记录集,为什么还要使用 TADOQuery?
  • 这只是为了演示,我可以使用 TADODataSet 正如您在回答中所显示的那样。我回答的关键部分是最后一段。
  • 是的,您不需要将连接属性分配给数据集。 _Recordset 中的连接仍然有效!
猜你喜欢
  • 2019-09-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 2020-12-09
  • 1970-01-01
  • 1970-01-01
  • 2019-11-02
相关资源
最近更新 更多