2017-06-28 3 views
-1

Ich versuche, den offenen Cursor als Ersatz für execute direkt zu verwenden, da meine SQL-Anweisung mehrere Datensätze zurückgeben könnte.'open cursor' als 'execute execute' verwenden

open cur1 for rule_sql; 
    loop   
    dbms_output.put_line(cur1.rule_id); 
    end loop; 
close cur1; 

Es wirft einen Fehler zu sagen: "PLS-00487: ungültiger Verweis auf Variable 'CUR1'"

Hat jemand ähnliche Probleme gehabt? Jede Hilfe wird sehr geschätzt :)

Antwort

2

Der Cursor ist nur ein Zeiger auf eine Ergebnismenge. Um seinen Inhalt zu referenzieren, müssen Sie fetch in eine Variable einfügen. Beachten Sie, dass die Variable ein Datensatztyp sein muss, der der Projektion der Abfrage entspricht. Dies kann schwierig sein, wenn Sie dynamisches SQL verwenden, um eine flüssige Gruppe von Spalten zu implementieren.

Wie auch immer, so etwas wie diese:

declare 
    cur1 sys_refcursor; 
    Type cur_rec is record (
     rule_id number, 
     rule_desc varchar2(32)); 

    row1 cur_rec; 
    .... 
Begin 
    ... 
    open cur1 for stmt; 
    for row1 in cur1 loop 
      Dbms_output.put_line(row1.rule_id); 
    End loop; 
    .... 
End; 

„Wenn ich die Art der Spalt im Ergebnis nicht wissen, dann kann ich nicht eine Variable erstellen, um die Cursor-Werte zu erfassen“

Das Leben ist komplizierter, wenn Sie die Projektion Ihrer Abfrage zur Kompilierzeit nicht kennen. Sie können Native Dynamic SQL nicht mehr verwenden, Sie müssen den vollständigen DBMS_SQL verwenden.

In 11g führte Oracle die sogenannte Methode 4 Dynamic SQL ein. Dies erlaubt uns, variable Projektionen auf Kosten von viel mehr Code zu verarbeiten. Adrian Billington hat auf seiner Website Oracle-developer.net eine ausgezeichnete Einführung dazu geschrieben. Check it out

+0

Hallo @APC: Vielen Dank für die Zeit nehmen .. Wenn ich eine Variable nicht die Art der Spalten im Ergebnis wissen, dann kann ich nicht erstellen um die Cursorwerte zu erfassen .. ist es? – thealchemist

+0

Das Leben wird härter. Welche Oracle-Version verwenden Sie? – APC

+0

Ich verwende die Version 4.1.5 :) – thealchemist

1

Sie die fetch Aussage verpasst haben - siehe Example 7.4 in docs

open cur1 for rule_sql; 
loop   
    fetch cur1 into my_row_variable; 
    exit when cur1%notfound; 
    dbms_output.put_line(cur1.rule_id); 
end loop; 
close cur1; 
+0

hi @tony: wenn ich nicht weiß, ob es eine Spalte mit dem Namen 'rule_id' geben wird und ich die gesamte Cursor-Ausgabe sehen möchte .. gibt es eine Möglichkeit dazu? Ich habe put_line (cur1) ausprobiert, aber das funktioniert nicht. – thealchemist

+0

In diesem Fall müssen Sie das [DBMS_SQL-Paket] (http://docs.oracle.com/database/121/ARPLS/d_sql.htm#ARPLS058) verwenden und die Lösung ist viel komplizierter. In dieser Dokumentation gibt es verschiedene Beispiele. –