Oracle PL / SQL – ORA-01403 "Keine data gefunden" bei Verwendung von "SELECT INTO"

Ich habe bei der Entwicklung eines Triggers in Oracle auf dieses Problem gestoßen: ORA-01403: keine data gefunden . Ich habe etwas recherchiert und die Ursache des Problems verstanden. Trotzdem verhindert die Behandlung der Fehlerausnahme den obigen Fehler, triggers aber mein Problem nicht.

Was ich derzeit suche, ist eine optimale Problemumgehung, um den geringeren Suchanfragenumfang zu erreichen / die bestmögliche performance zu erzielen. Ich werde versuchen, das Szenario zu beschreiben, indem ich einfache Beispiele für die reale Struktur erstelle.

Szenario

Ich habe eine "datesreferenz" -Tabelle, um timeräume zu bestimmen, sagen wir:

CREATE TABLE DATE_REFERENCE ( DATE_START DATE NOT NULL, DATE_END DATE NOT NULL, -- Several other columns here, this is just a silly example CONSTRAINT PK_DATE_REFERENCE PRIMARY KEY(DATE_START, DATE_END) ); 

Wenn der Auslöser ausgetriggers wird, habe ich ein DATE Feld – sagen wir DATE_GIVEN (zum Beispiel Sake). Was ich brauche ist:

  1. So finden Sie die Zeile DATE_REFERENCE in der DATE_GIVEN BETWEEN DATE_START AND DATE_END (einfach); ODER
  2. Wenn die vorherige Option keine data zurückgibt, muss ich den nächsten DATE_START zu DATE_GIVEN .

In beiden Fällen muss ich die Zeile mit allen Spalten aus der Tabelle DATE_REFERENCE , unabhängig davon, ob sie mit Opt 1 oder 2 übereinstimmt. Genau dort ist das beschriebene Problem DATE_REFERENCE .

Ich habe diesen Testblock geschrieben, um zu testing und zu versuchen, eine Lösung zu finden. Das folgende Beispiel funktioniert nicht , ich weiß; aber genau das möchte ich (im Konzept) erreichen. Ich habe Kommentare wie -- Lots of code hinzugefügt, um klarzustellen, dass dies Teil eines komplizierteren Auslösers sein wird:

 DECLARE DATE_GIVEN DATE; RESULTROW DATE_REFERENCE%ROWTYPE; BEGIN -- Lots of code -- Lots of code -- Lots of code DATE_GIVEN := TO_DATE('2014-02-26 12:30:00', 'YYYY-MM-DD HH24:MI:SS'); -- This one throws the ORA-01403 exception if no data was found SELECT * INTO RESULTROW FROM DATE_REFERENCE WHERE DATE_GIVEN BETWEEN DATE_START AND DATE_END; -- If the above didn't throw exceptions, I would continue like so: IF RESULTROW IS NULL THEN SELECT * INTO RESULTROW FROM DATE_REFERENCE WHERE DATE_START > DATE_GIVEN AND ROWNUM = 1 ORDER BY DATE_START ASC; END IF; -- Now RESULTROW is populated, and the rest of the trigger code gets executed ~beautifully~ -- Lots of code -- Lots of code -- Lots of code END; 

Frage

Wenn Sie wissen, dass der oben genannte PL / SQL-Block eher ein Konzept als ein funktionierender Code ist , was ist der beste path, um RESULTROW zu RESULTROW , die Performance zu überwachen und weniger Abfragen durchzuführen?

Sorry für die lange Frage, aber ich dachte Szenario-Erklärung war notwendig. Vielen Dank im Voraus für jede Hilfe / Gedanken!

Solutions Collecting From Web of "Oracle PL / SQL – ORA-01403 "Keine data gefunden" bei Verwendung von "SELECT INTO""

rownum einfach das Feld direkt aus und verwenden Sie dazu ordering und rownum :

 SELECT * INTO RESULTROW FROM (SELECT * FROM DATE_REFERENCE ORDER BY (CASE WHEN DATE_GIVEN BETWEEN DATE_START AND DATE_END THEN 1 ELSE 0 END) DESC, (DATE_START - DATE_GIVEN) ) t WHERE rownum = 1; 

Dies füllt die Informationen mit einer Abfrage.

BEARBEITEN:

Wenn Sie eine Bedingung in die Unterabfrage stellen möchten, muss diese wie folgt lauten:

 SELECT * INTO RESULTROW FROM (SELECT * FROM DATE_REFERENCE WHERE DATE_GIVEN <= DATE_END ORDER BY (CASE WHEN DATE_GIVEN BETWEEN DATE_START AND DATE_END THEN 1 ELSE 0 END) DESC, (DATE_START - DATE_GIVEN) ) t WHERE rownum = 1; 

Ich glaube, die richtige Bedingung ist DATE_GIVEN <= DATE_END . Dies gilt sowohl für die Bedingung between als auch für DATE_GIVEN < DATE_START . Dies setzt voraus, dass DATE_END niemals NULL .