Einzelnen Beitrag anzeigen

Robert_G
(Gast)

n/a Beiträge
 
#6

Re: Große Datenmengen in Oracle 9i häppchenweise fetchen

  Alt 28. Sep 2004, 12:57
HiHi, ich merke gerade, dass ich mir um 23:00 und ohne Ora keine solchen Sachen aus den Fingern saugen sollte.


So ist's gleich viel einfahcer:
  • Spec:
    SQL-Code:
    create or replace package fetch$F_VBO_DC_OVERVIEW is

      function FetchRecs
      (
        iRecLimit in integer
       ,ioTable in out nocopy tbl$F_VBO_DC_OVERVIEW
      ) return integer;

    end;
  • Body:
    SQL-Code:
    create or replace package body fetch$F_VBO_DC_OVERVIEW is

      cursor cur$F_VBO_DC_OVERVIEW is
        SELECT rec$F_VBO_DC_OVERVIEW(A
                                    ,B
                                    ,C)
        FROM F_VBO_DC_OVERVIEW;

      function FetchRecs
      (
        iRecLimit in integer
       ,ioTable in out nocopy tbl$F_VBO_DC_OVERVIEW
      ) return integer is
      begin
        if not cur$F_VBO_DC_OVERVIEW%IsOpen then
          open cur$F_VBO_DC_OVERVIEW;
          dbms_application_info.set_action('cursor opened');
        end if;
      
        fetch cur$F_VBO_DC_OVERVIEW bulk collect
          INTO ioTable limit iRecLimit;
        if cur$F_VBO_DC_OVERVIEW%NotFound then
        
          declare
            RecCount integer := cur$F_VBO_DC_OVERVIEW%rowcount;
          begin
            close cur$F_VBO_DC_OVERVIEW;
            dbms_application_info.set_action('cursor closed (' || RecCount || ' records)');
          
          end;

          return 0;
        else
          dbms_application_info.set_action(cur$F_VBO_DC_OVERVIEW%rowcount || ' records fetched');
          return 1;
        end if;
      end;

    begin
      dbms_application_info.set_module('test fetching chunks of data'
                                      ,'initialize package');
    end;

Der cursor kann im Body des Package versteckt werden. Da eine Package variable über den Zeitraum einer Session "am Leben" bleibt, braucht man keinen RefCursor mehr hin & her zuschieben.

Du musst jetzt nur noch herausfinden, wie du ein Objekt vom Typ tbl$F_VBO_DC_OVERVIEW mit deiner Anwendung verbinden kannst.
In DOA würde das so aussehen (Wobei ich in DOA einfach SomeQuery.Threaded := true geschrieben hätte, ohne das package und den ganzen Käse ):
Delphi-Quellcode:
var
  RecLimit :integer;
  tblRecords :TOracleObject;
  SomeQuery :TOracleQuery;
begin
  //...
  RecLimit := 1000;
  tblRecords := TOracleObject.Create(SomeSession, 'tbl$F_VBO_DC_OVERVIEW','');
  SomeQuery := TOracleQuery.Create(nil);
  try
   
    with SomeQuery do
    begin
       Session := SomeSession;
       DeclareVariable('oRecCount', otInteger);
       DeclareAndSetVariable('iRecLimit', otInteger, RecLimit);
       DeclareVariable('ioTable', otObject);
       SetComplexVariable('ioTable', tblRecords);
       SQL.Text :=
         'begin';
         ' :oRecCount := fetch$F_VBO_DC_OVERVIEW.FetchRecs(:iRecLimit, :ioTable);' + #10 +;
         'end;';
    end;
  
    repeat
       SomeQuery.Execute();
       // Mach' irgendwas mit tblRecords
    until IrgendWas = IrgendWasAnderes;
  finally
    SomeQuery.Free();
  end;
  Mit Zitat antworten Zitat