Haufenweise: Bulk Insert, Update, Delete

April 24, 2006 by Michael

Bulk Methoden in PL/SQL sind praktisch und schnell. Auch recht einfach anzuwenden. Allerdings ist mir in Oracle 9.2.0.6 ein sehr komisches Verhalten aufgefallen:

DECLARE
  TYPE id_table IS TABLE OF NUMBER;
  objekt_ids id_table;
BEGIN
    SELECT id
    BULK COLLECT INTO objekt_ids
    FROM   irgendwas
    WHERE  irgendwasanderes = 'wasweißich';
 
    FORALL idx IN objekt_ids.first .. objekt_ids.last
      DELETE FROM table1 WHERE objekt_id = objekt_ids(idx);
 
    FORALL idx IN objekt_ids.first .. objekt_ids.last
      DELETE FROM table2 WHERE objekt_id = objekt_ids(idx);
 
    -- ...
END;

Das Beispiel ist jetzt natürlich erstmal sinnlos, ist aber auch egal. Der Haken an der Sache: Das BULK COLLECT INTO Statement wirft keine NO_DATA_FOUND Exception, wenn die Ergebnismenge leer ist (im Gegensatz zu einem normalen SELECT INTO). Nichts desto trotz ist object_ids danach eine korrekt initialisierte Zusammenstellung.

War die Ergebnismenge leer, gibt es trotzdem eine Exception. Und zwar eine INVALID_NUMBER. Aus irgendeinem Grund laufen die forall Schleifen, auch wenn die virtuelle Tabelle leer ist.

Deshalb gilt für BULK Methoden: Abfragen, ob die Indextabellen leer sind!

DECLARE
  TYPE id_table IS TABLE OF NUMBER;
  objekt_ids id_table;
BEGIN
  IF(objekt_ids.COUNT > 0)THEN
    SELECT id
    BULK COLLECT INTO objekt_ids
    FROM   irgendwas
    WHERE  irgendwasanderes = 'wasweißich';
 
    FORALL idx IN objekt_ids.first .. objekt_ids.last
      DELETE FROM table1 WHERE objekt_id = objekt_ids(idx);
 
    FORALL idx IN objekt_ids.first .. objekt_ids.last
      DELETE FROM table2 WHERE objekt_id = objekt_ids(idx);
 
    -- ...
  END IF;
END;

2 comments

  1. Gast wrote:

    Bin durch zufall auf diese Seite gestoßen!
    Vielen Dank für den Hinweis, dass beim Bulk Collect keine NO_DATA_FOUND exception geworfen wird!

    Ich habe mich jetzt ca. 1h mit diesem dummen Problem aufgehalten… und habe endlich hier die Lösung gefunden 🙂

    Schönen Tag noch!

    Posted on May 14, 2007 at 8:03 PM | Permalink
  2. Michael wrote:

    Gerne! Vielen Dank für die nette Rückmeldung!

    Posted on May 14, 2007 at 9:22 PM | Permalink
Post a Comment

Your email is never published. We need your name and email address only for verifying a legitimate comment. For more information, a copy of your saved data or a request to delete any data under this address, please send a short notice to michael@simons.ac from the address you used to comment on this entry.
By entering and submitting a comment, wether with or without name or email address, you'll agree that all data you have entered including your IP address will be checked and stored for a limited time by Automattic Inc., 60 29th Street #343, San Francisco, CA 94110-4929, USA. only for the purpose of avoiding spam. You can deny further storage of your data by sending an email to support@wordpress.com, with subject “Deletion of Data stored by Akismet”.
Required fields are marked *