Zum Inhalt springen

[Oracle PL/SQL] Datensätze updaten


Ganymed

Empfohlene Beiträge

Hallo zusammen,

ich habe hier eine riesige Datenmenge, die komplett geupdatet werden muss.

Leider sind das ziemlich viele, und weil das so lange braucht, müsste ich das entweder mitten in der Nacht machen (wo ich vermutlich andere Jobs mit stören würde) oder es "etappenweise" machen über mehere Tage verteilt.

Nun meine Frage:

Gibt es irgendeine Möglichkeit, sich immer nur - sagen wir mal - 1000 Datensätze updaten zu lassen? Per SQL-Befehl?

Sowas wie:

Update die ersten 1000 DS von meiner Tabelle Set Attribut = Wert;

Und dann am nächsten Tag weitere 1000.

Leider sind die DS nicht alle durchgängig nummeriert (durch Löschungen).

Ich würde auch ein PL/SQL Skript schreiben, habe aber jetzt auch keine Idee, wie ich das am dümmsten mache, ohne dass das noch länger dauert.

Meine Idee war, eine Schleife (oder Cursor) zu basteln, die 1000 Durchläufe hat.

Bei jedem Durchlauf suche ich mir den Primärschlüssel des DS heraus und update genau diesen.

Nur, was mache ich, wenn ich neu am nächsten Tag ansetzen will? Wie finde ich heraus, was der nächste DS ist, den ich updaten muss? Ok, ich kann prüfen, ob das Feld, was ich updaten will noch nicht meinen gewünschten Wert hat.

Aber irgendwie find ich es komisch, dann den erstbesten gefunden Wert als Startwert zu nehmen?

Irgendwie steh ich tierisch auf dem Schlauch und einen SQL Befehl mit der o.g. Möglichkeit hab ich auch nicht gefunden.

Gruß

Ganymed

Link zu diesem Kommentar
Auf anderen Seiten teilen

gugug gany,

sind die daten nur in einer oder über mehrere tabellen verteilt?

ist die tabelle/sind die tabellen partitioniert?

sind indizes auf verschiedenen upzudatenden tabellenspalten vorhanden?

allenfalls noch den status und die uniqueness des index?

kannst du falls möglich mal ein DESC der tabelle reinkleben?

1000 datensätze am tag PER UPDATE zu verarbeiten scheint mir gar wenig zu sein. das ist oracle, nicht mysql *duckundrenn* :D die idee mit dem cursor ist aber nicht so daneben, allenfalls hilft dir ROWNUM oder die ROWID bei deiner arbeit, wobei letztere allerdings zwar tabellenweit, aber nicht datenbankweit eindeutig ist.

s'Amstel

Link zu diesem Kommentar
Auf anderen Seiten teilen

gugug gany,

sind die daten nur in einer oder über mehrere tabellen verteilt?

ist die tabelle/sind die tabellen partitioniert?

sind indizes auf verschiedenen upzudatenden tabellenspalten vorhanden?

allenfalls noch den status und die uniqueness des index?

kannst du falls möglich mal ein DESC der tabelle reinkleben?

1000 datensätze am tag PER UPDATE zu verarbeiten scheint mir gar wenig zu sein. das ist oracle, nicht mysql *duckundrenn* :D die idee mit dem cursor ist aber nicht so daneben, allenfalls hilft dir ROWNUM oder die ROWID bei deiner arbeit, wobei letztere allerdings zwar tabellenweit, aber nicht datenbankweit eindeutig ist.

s'Amstel

1) Es bezieht sich nur auf eine Tabelle (zum Glück ;))

2) Nein, sind sie nicht

3) Nein, auf dem Attribut lieg kein Index

4) Nein

5) EIn desc im Update? Was soll mir das bringen? :)

Die 1000 war ja auch nur ein Beispiel. Da das immer dann gemacht werden muss, wenn kein Anwender auf der DB ist, ist mein Zeitrahmen leider klein. Je nachdem wie schnell das geht, kann man das ja auch erhöhen :)

ROWID... Hmmm... Nur wie finde ich quasi meinen letzen geupdateten DS wieder am nächsten Tag und kann da wieter machen, wo ich aufgehört habe? :confused:

Link zu diesem Kommentar
Auf anderen Seiten teilen

hallo,

erstmal: desc ist nicht nur ein schluesselwort fuer ORDER BY sondern auch die

kurzschreibweise fuer describe.

zweitens:

um wieviele Datensaetze handelt es sich ?

Bei <1000000000 kann dies -nach deinen Angaben- nicht lange dauern.

vorausgesetzt ist ein ausreichend dimensionierter Undo-Tablespace.

gruss / zirri

Link zu diesem Kommentar
Auf anderen Seiten teilen

Ich habe gerade eine "wilde" theorie gestrickt:

Also:

Ich deklariere einen Cursor, der mir die ID (=Primärschlüssel) und das upzudatende Attribut ausspuckt.

Dann durchlaufe ich den Cursor und setze in den Cursor einen Zähler, der bis 1000 hochgeht.

Anschließend fahrich ein Update auf den Datensatz mit Hilfe der ID.

Ungefähr so:


CURSOR MeinUpdateCursor IS 

       SELECT ID

       FROM meinerTabelle

       WHERE Attribut ='';  


OPEN MeinUpdateCursor;

         LOOP

              FETCH ID INTO cID,;

              EXIT WHEN MeinUpdateCursor%NOTFOUND;  


              BEGIN

                    IF Zaehler < 1000 then

                          update meineTabelle set Attribut = Wert where ID = cID;

                          Zaehler := Zaehler +1;

                    end if;


              EXCEPTION


                   WHEN NO_DATA_FOUND THEN

                          dbms_output.putline("Nix mehr gefunden");

              END;         

         END LOOP;

    CLOSE MeinUpdateCursor; 

Bitte jetzt nicht auf Korrektheiut prüfen, ist jetzt runtergehackt :D

Damit könnte ich doch 1000 DS updaten. Durch das Statement im Cursor bekomme ich immer alle noch nicht geupdateten Atribute angezeigt (da leer).

Ginge das?

@zirri

Es dauert lange...

Ich machs hier im Testsystem und das dauert schon seit 2 1/2h... Das Zeitfenster hab ich definitv nicht.

Link zu diesem Kommentar
Auf anderen Seiten teilen

sorry, war etwas missverständlich - wie zirri schon meinte:

SQL> DESC(RIBE) TEST

 Name                                      Null?    Typ

 ----------------------------------------- -------- ----------------------------

 S_ID                                               NUMBER

 S_BLOB                                             BLOB

 DATEINAME                                          CLOB

 TEXT1                                              VARCHAR2(30)

 ZAHL                                               NUMBER(3)

 SSS                                                NUMBER

 INT                                                NUMBER(38)


SQL> 

wenn die konsistenz deiner ROWIDs nicht durch partitionierte tabellen index-origanisierte tabellen o.ä. gefährdet ist, hast du innerhalb einer tabelle für jede zeile eine eindeutige ROWID. aber ich denke, es ist auch ohne lösbar.

du hast erwähnt, dass deine updates land dauern. kannst du bei so einem update ein trace auf die session bzw. explain auf das statement machen? im udump-verzeichnis sollte bei ersterem etwas zu finden sein, was dir sagt, wieviele calls und parses die datenbank gemacht hat.

s'Amstel

Link zu diesem Kommentar
Auf anderen Seiten teilen

Dein Kommentar

Du kannst jetzt schreiben und Dich später registrieren. Wenn Du ein Konto hast, melde Dich jetzt an, um unter Deinem Benutzernamen zu schreiben.

Gast
Auf dieses Thema antworten...

×   Du hast formatierten Text eingefügt.   Formatierung wiederherstellen

  Nur 75 Emojis sind erlaubt.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Editor leeren

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

Fachinformatiker.de, 2024 by SE Internet Services

fidelogo_small.png

Schicke uns eine Nachricht!

Fachinformatiker.de ist die größte IT-Community
rund um Ausbildung, Job, Weiterbildung für IT-Fachkräfte.

Fachinformatiker.de App

Download on the App Store
Get it on Google Play

Kontakt

Hier werben?
Oder sende eine E-Mail an

Social media u. feeds

Jobboard für Fachinformatiker und IT-Fachkräfte

×
×
  • Neu erstellen...