tutorials.de Buch-Aktion 05/2012
Like Tree1Danke
  • 1 Beitrag von Exceptionfault
ERLEDIGT
JA
ANTWORTEN
5
ZUGRIFFE
2703
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    zuckerbrini zuckerbrini ist offline Mitglied Silber
    Registriert seit
    Nov 2008
    Ort
    Niederösterreich
    Beiträge
    83
    Hallo!
    Ich habe eine Cursor For Schleife, die mir sehr viele Datensätze (ca 60000) zurückgibt.
    Um einen Abbruch wegen einem zugroßen Rollbacksegement zu verhinden, möchte ich alle 1000 Datensätze ein Commit oder Rollback (je nach Auswahl) machen.

    Da ich das Commit ganz einfach in der For Schleife mache mit einer Überprüfung:
    [CODE] IF(v_zahl >= 1000) THEN
    COMMIT;
    v_zahl := 0;
    END IF;
    CODE]
    bekomm ich ja nun logischer Weise die Fehlermeldung "fetch out of sequence".

    Mir fehlt jetzt nur grad eine Idee wie ich das realisieren könnte.

    Kann mir irgendwer einen Denkanstoß geben?
     

  2. #2
    Avatar von Exceptionfault
    Exceptionfault Exceptionfault ist offline Mitglied Brokat
    Registriert seit
    Sep 2004
    Ort
    Neckarsulm
    Beiträge
    348
    Zunächst einmal: 60000 ist nicht viel sofern deine Zeilen keine LOBs enthalten oder gerade 200 VARCHAR(4000) Spalten haben. Und die Rollbacksegmente sollte sowas auch nicht stressen, ansonsten sind sie wohl eher zu klein dimensioniert. BTW, wenn du von Rollbacksegmenten sprichst, nutzt ihr noch 8i?

    Eine Methode das zu umgehen, wäre den kompletten Cursor erst zu fetchen und zu schliessen und dann erst durch die Datensätze loopen und zwischendurch committen.

    Anstatt also einem OPEN Cursor und FETCH LOOP einen BULK COLLECT machen, das ist obendrein wesentlich schneller.
    Code sql:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    
    DECLARE 
        TYPE mytable IS TABLE OF <cursor name>%ROWTYPE;
        resultset mytable;
    BEGIN
        OPEN cursor_name;
        FETCH cursor_name BULK COLLECT INTO resultset;
        CLOSE cursor_name;
        
        FOR i IN resultset.FIRST .. resultset.LAST LOOP
        
            ...
        
            IF MOD( i, 1000 ) = 0 THEN
                COMMIT;
            END IF;
        
        END LOOP;
    END;
    /

    Generell sollte ein COMMIT aber niemals aus Rücksicht auf Rollbacksegmente oder sonstigen Parametern gemacht werden sondern sinnvollerweise nach der Anforderung des Businessfalls... immer an den Deasasterfall denken, was passiert wen dnach 36000 Datensätze meine DB wegfliegt? Die hälfte ist geändert und commited, die andere Hälfte nicht...?!
    zuckerbrini bedankt sich. 
    liebe Grüße
    Exceptionfault (http://exceptionfault.de)

    Never say: "Always"! Always say: "Never say never"! - Tom Kyte @ Ask Tom Live in Berlin 2008

  3. #3
    zuckerbrini zuckerbrini ist offline Mitglied Silber
    Registriert seit
    Nov 2008
    Ort
    Niederösterreich
    Beiträge
    83
    Ja in diesem Fall 8i
    Bekomm das leider noch immer nicht wirklich hin. Hab alles genauso wie du gemacht. Leider bekomme ich aber immer bei der Zeile
    FETCH cursor_name BULK COLLECT INTO resultset;
    Diese Meldung
    PLS-00597: expression resultset in the INTO list is of wrong type

    Was hab ich da falsch gemacht?
     

  4. #4
    dbwizard dbwizard ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Zürich
    Beiträge
    285
    Zitat Zitat von zuckerbrini Beitrag anzeigen
    Ja in diesem Fall 8i
    Bekomm das leider noch immer nicht wirklich hin. Hab alles genauso wie du gemacht. Leider bekomme ich aber immer bei der Zeile
    FETCH cursor_name BULK COLLECT INTO resultset;
    Diese Meldung
    PLS-00597: expression resultset in the INTO list is of wrong type

    Was hab ich da falsch gemacht?
    Hallo,

    Wenn ich mich noch richtig erinnere (8i ist schon soooo lange her), unterstützt die 8er keine bulk collects in array of records.
     

  5. #5
    zuckerbrini zuckerbrini ist offline Mitglied Silber
    Registriert seit
    Nov 2008
    Ort
    Niederösterreich
    Beiträge
    83
    Ok gut dann also keine Bulk Collections.
    Aber wie kann ich das ganze dann ohne Bulk Collections machen?
     

  6. #6
    dbwizard dbwizard ist offline Mitglied Brokat
    Registriert seit
    May 2007
    Ort
    Zürich
    Beiträge
    285
    Zitat Zitat von zuckerbrini Beitrag anzeigen
    Aber wie kann ich das ganze dann ohne Bulk Collections machen?
    - Indem du sie weglässt ? Aber im Ernst, ich würde dir dazu raten, dass ganze mit dem Commit zu vergessen. Du
    - verschenkst Ressourcen
    -es ist langsamer
    -nicht transparent (Stichwort "Wiederholbar")

    Gruss
     

Ähnliche Themen

  1. Selbstaufrunfende Prozedur in Cursor-Schleife
    Von mackel90 im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 30.04.08, 23:47
  2. Cursor falscher typ ORACLE
    Von cullmann im Forum Relationale Datenbanksysteme
    Antworten: 0
    Letzter Beitrag: 08.02.07, 22:18
  3. Oracle 9i - PL/SQL zeiger auf statische cursor
    Von Matthias_Nordwig im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 11.08.06, 18:09
  4. Oracle 9.2.0.6i; Auto Commit
    Von tplanitz im Forum Relationale Datenbanksysteme
    Antworten: 3
    Letzter Beitrag: 26.12.05, 20:21
  5. Oracle Cursor anhand einer if Bedingung erstellen
    Von Eichhoernchen09 im Forum Relationale Datenbanksysteme
    Antworten: 2
    Letzter Beitrag: 06.11.05, 09:01