Ganymed Geschrieben 15. März 2006 Teilen Geschrieben 15. März 2006 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Amstelchen Geschrieben 15. März 2006 Teilen Geschrieben 15. März 2006 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* 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ganymed Geschrieben 15. März 2006 Autor Teilen Geschrieben 15. März 2006 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* 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: Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
zirri Geschrieben 15. März 2006 Teilen Geschrieben 15. März 2006 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ganymed Geschrieben 15. März 2006 Autor Teilen Geschrieben 15. März 2006 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 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. Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Amstelchen Geschrieben 15. März 2006 Teilen Geschrieben 15. März 2006 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 Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Ganymed Geschrieben 15. März 2006 Autor Teilen Geschrieben 15. März 2006 Ok, meine o.g. Idee klappt Dauert zwar was, bis alle geupdatet ist, aber so kann man das mal zwischendurch machen Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
mme Geschrieben 17. März 2006 Teilen Geschrieben 17. März 2006 stellt sich die Frage warum du das nur machen kannst wenn sonst keiner auf der Datenbank ist? Wegen peroformance / Sperren oder aus fachlichen Gründen? Du kannst ja alle 100 DS einen commit absetzen in deinem PL/SQL oder ähnliches... Zitieren Link zu diesem Kommentar Auf anderen Seiten teilen Mehr Optionen zum Teilen...
Empfohlene Beiträge
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.